Collection values overwritten if item elements are not contiguous (mixed content)
Looks like we have a bug in the parser. Parsing next simple document leads to data loss.
<Data>
<foo>foo1</foo>
<foo>foo2</foo>
<bar>bar1</bar>
<foo>foo3</foo>
<foo>foo4</foo>
</Data>
Expected result: foo java-property contains list of 4 values.
Actual result: foo java-property contains list of 2.
Setter for foo property is called two times for every tags group: foo1, foo2 and foo3, foo4. Second setter call overrides data gathered by the first call. As result parsing result contains foo list as foo3, foo4 instead of expected foo1, foo2, foo3, foo4.
Here is a java-code to reproduce the issue.
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlCData;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import java.util.List;
@JacksonXmlRootElement(localName = "data")
class Data {
@JacksonXmlCData
@JacksonXmlElementWrapper(useWrapping = false)
@JacksonXmlProperty
private List<String> foo;
@JacksonXmlCData
@JacksonXmlElementWrapper(useWrapping = false)
@JacksonXmlProperty
private List<String> bar;
public List<String> getFoo() {
return foo;
}
public void setFoo(List<String> foo) {
this.foo = foo;
}
public List<String> getBar() {
return bar;
}
public void setBar(List<String> bar) {
this.bar = bar;
}
}
public class Foo {
public static void main(String[] args) throws JsonProcessingException {
String xml = ""
+ "<Data>"
+ " <foo>foo1</foo>"
+ " <foo>foo2</foo>"
+ " <bar>bar1</bar>"
+ " <foo>foo3</foo>"
+ " <foo>foo4</foo>"
+ "</Data>";
XmlMapper m = new XmlMapper();
Data data = m.readValue(xml, Data.class);
System.err.println(data.getFoo()); // Expected ["foo1", "foo2", "foo3", "foo4"] but ["foo3", "foo4"] given.
}
}
jackson-dataformat-xml version: 2.10.0
Yes. This is a known problem, and due to difficulty in changing handling it is unlikely to be improved upon any time soon.
I see. Thank you for the reply.
Actually... you may be able to work around this issue by overriding setters (set methods) to add values into existing list, instead of replace, and initializing fields into empty Lists (or have setter check to initialize if null).
In fact there is even another method, available with 2.9 and later: see "@JsonSetter" explanation on https://medium.com/@cowtowncoder/jackson-2-9-features-b2a19029e9ff -- using which you can get "merge" functionality that also should work around the issue.
This is the way I use to solve the issue. Thank you.
Ok good. Maybe this helps others to find it too.