pdvrieze / xmlutil

XML Serialization library for Kotlin
https://pdvrieze.github.io/xmlutil/
Apache License 2.0
363 stars 30 forks source link

XmlOtherAttributes: deserialization replaces keys by its value #190

Closed ArtRoman closed 1 month ago

ArtRoman commented 6 months ago
    @Test
    fun testXmlMapSerialization() {
        @Serializable
        data class Container(
            @XmlOtherAttributes
            val attributes: Map<String, String>
        )

        val container = Container(
            mapOf(
                "key1" to "value1",
                "key2" to "value2",
            ),
        )
        println("Original object: $container")

        val xml = XML.encodeToString(Container.serializer(), container)
        println("Serialized: $xml")

        val container2 = XML.decodeFromString<Container>(xml)
        println("Deserialized: $container2")

        val xml2 = XML.encodeToString(Container.serializer(), container2)
        println("Serialized again: $xml2")

        Assert.assertEquals(container, container2)
        Assert.assertEquals(xml, xml2)
    }

Output:

Original object: Container(attributes={key1=value1, key2=value2})
Serialized: <Container key1="value1" key2="value2" />
Deserialized: Container(attributes={value1=value1, value2=value2})
Serialized again: <Container value1="value1" value2="value2" />

Expected :Container(attributes={key1=value1, key2=value2})
Actual   :Container(attributes={value1=value1, value2=value2})

Serialization of a map with @XmlOtherAttributes attribute works correctly, but after deserialization names of the keys are replaced by its values.

ArtRoman commented 6 months ago

Checked on 0.86.0—0.86.3, reproducible on all versions

pdvrieze commented 6 months ago

It is certainly a bug in the library. I suspect it was exposed by kotlinx.serialization better supporting non-string keys (the string only path worked). In any case I have fixed this. It should be available in the snapshot release. In the meantime the "recommended" and working way is to use (Serializable)QName as the key type. This will also work in all cases, not only for keys in the null namespace.

ArtRoman commented 2 months ago

Hello. Will you make a library release with all fixes before the kotlin 2.0? The kotlin was updated to 1.9.23 in March, and kotlinx-serizalization was updated to version 1.6.3 in February since the last XmlUtil release.

pdvrieze commented 2 months ago

@ArtRoman I'll probably do this, I'm quite busy with other work at the moment. I can certainly make sure that there is a 1.9 release in any case.