Given XML in the following (simplified) format:
<outer><inner><field1>a</field1><field2>b</field2><field3>c</field3></inner></outer>
I'd like to deserialize the <inner>
element into a class representing that and discard the rest.
public class Inner {
private String field1;
private String field2;
private String field3;
// getters, setters, ctor
}
I am using the Jackson XmlMapper
class to perform the deserialization. If I strip <outer>
out of the xml string obviously it works.
XmlMapper xmlMapper = new XmlMapper();
// in my scenario the `<inner>` element actually contains fields I don't care about
xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Inner inner = xmlMapper.readValue(xml, Inner.class);
System.out.println(inner);
// Inner(field1=a, field2=b, field3=c)
If I leave the <outer>
element all of the fields in inner
are null.
I've tried annotating the Inner
class with @JacksonXmlRootElement(localName = "inner")
but that didn't change the output.
I could create a class that represents the <outer>
element but that seems wasteful. I could probably also create a new string containing just the xml between the <inner>
elements, but again that feels a bit hacky.
In my case the xml is being broadcast by a separate system that I have no control over, so I can simply amend the xml structure.
Is it possible to deserialize the "inner" xml into a new class instance?
It seems that for @JacksonXmlRootElement(localName = "inner")
to work as you expect you also need UNWRAP_ROOT_VALUE. E.g.
xmlMapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
I can't say the above is very obvious from the docs.