jackson-dataformat-xml icon indicating copy to clipboard operation
jackson-dataformat-xml copied to clipboard

Jackson XML reading mixed sibling nodes "overwriting" issue

Open chengyiuchun opened this issue 10 months ago • 3 comments

Jackson seems to be overwriting the older sibling nodes if the order is mixed. See below test case. Seems to be a bug. Thanks.

@JacksonXmlRootElement
data class RootNode(
    @JacksonXmlElementWrapper(useWrapping = false)
    @JacksonXmlProperty(localName = "NodeA")
    val nodeA: List<NodeA>,
    @JacksonXmlProperty(localName = "NodeB")
    val nodeB: NodeB
)

data class NodeA(
    @JacksonXmlProperty(localName = "attr", isAttribute = true)
    val attr: String
)

data class NodeB(
    @JacksonXmlProperty(localName = "attr", isAttribute = true)
    val attr: String
)

class ReadXMLTest {
    @Test
    fun canRead() {
        val xml = """
            <RootNode>
                <NodeA attr="123"/>
                <NodeB attr="ABC"/>
                <NodeA attr="456"/>
            </RootNode>
        """.trimIndent()

        val xmlMapper = XmlMapper()
        xmlMapper.registerModule(kotlinModule())

        assertEquals(
            RootNode(
                listOf(NodeA("123"), NodeA("456")),
                NodeB("ABC")
            ),
            xmlMapper.readValue<RootNode>(xml)
        )
    }
}

This fails with

Expected :RootNode(nodeA=[NodeA(attr=123), NodeA(attr=456)], nodeB=NodeB(attr=ABC))
Actual   :RootNode(nodeA=[NodeA(attr=456)], nodeB=NodeB(attr=ABC))

If the XML is like below, then it passes.

<RootNode>
    <NodeA attr="123"/>
    <NodeA attr="456"/>
    <NodeB attr="ABC"/>
</RootNode>

chengyiuchun avatar Jan 26 '25 08:01 chengyiuchun

This is the way things work unfortunately: there is no merging of dis-joint sequences of elements. It is unlikely to be resolved in near future.

But there is a work-around: if you add a setter method you can merge Lists on setter.

cowtowncoder avatar Jan 27 '25 01:01 cowtowncoder

Thanks. Due to other requirements we decided to write a custom deserializer for this.

chengyiuchun avatar Jan 29 '25 02:01 chengyiuchun

Ok best of luck!

cowtowncoder avatar Jan 29 '25 04:01 cowtowncoder