jackson-dataformat-xml
jackson-dataformat-xml copied to clipboard
Deserialization of heterogeneous list
Discussed in https://github.com/FasterXML/jackson-dataformat-xml/discussions/786
Originally posted by kristofvb November 19, 2025 Hi,
I have some questions about the following sample:
class ParseTest {
@Test
void parse() throws Exception {
var mapper = new XmlMapper();
var root = mapper.readValue("""
<root>
<foos>
<foo sequenceNr="1">somefoo</foo>
<foo sequenceNr="2">otherfoo</foo>
<bar>something very different</bar>
</foos>
</root>
""", Root.class);
System.out.println(root);
}
private static class Root {
@JacksonXmlProperty(localName = "foos")
private List<Foo> foos = new ArrayList<>();
public String toString() {
return "Root{" +
"foos=" + foos +
'}';
}
}
private static class Foo {
@JacksonXmlText
String text;
@JacksonXmlProperty(isAttribute = true)
Integer sequenceNr;
public String toString() {
return "Foo{" +
"text='" + text + '\'' +
", sequenceNr=" + sequenceNr +
'}';
}
}
}
- is there a way to make sure the foos list only contains Foo instances for actual foo elements and avoid turning the bar element into a Foo instance?
- is there a way (annotation) to sort the foos list on sequenceNr of the elements? Currently I sort the list in the foos setter (which I omitted in the sample).
Thanks for looking into this.
(by @kristofvb)
This test fails
class ParseTest {
@Test
void parse() throws Exception {
var mapper = new XmlMapper();
var root = mapper.readValue("""
<root>
<foos>
<foo sequenceNr="1">somefoo</foo>
<foo sequenceNr="2">otherfoo</foo>
<bar>something very different</bar>
</foos>
</root>
""", Root.class);
assertEquals(List.of(new Foo("somefoo", 1), new Foo("otherfoo", 2)), root.foos);
}
static class Root {
@JacksonXmlProperty
List<Foo> foos = new ArrayList<>();
}
static class Foo {
@JacksonXmlText
String text;
@JacksonXmlProperty(isAttribute = true)
Integer sequenceNr;
public Foo() {
}
public Foo(String text, Integer sequenceNr) {
this.text = text;
this.sequenceNr = sequenceNr;
}
@Override
public String toString() {
return "Foo{" +
"text='" + text + '\'' +
", sequenceNr=" + sequenceNr +
'}';
}
}
}