Search code examples
jsonxmljaxbjacksonjackson-dataformat-xml

XML deserialization using jackson-dataformat-xml custom root element?


So I am using Jackson for JSON serialization/deserialization succesfully uptil now, now I am also trying to use it for XML serialization/deserialization using it's jackson-dataformat-xml-2.3.0.jar.

I have used

objectmapper.reader(Student.class).withRootName("prefix:student").readValue(jsonString)

to deserialize my JSON (having root name with prefix) to Student class which worked succesfully.

Now, I am trying to deserialize my XML string (having root name with prefix) to Student :

XML:

<prefix:student>
  <name>
    Jack Jones
  </name>
  <id>1</id>
</prefix:student>

My POJO:

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "name",
        "id",
        ....
    })
    @XmlRootElement(name = "student")
    public class Student
    {

        protected String name;
        BigInteger id;  
..........................
    }

I was desrializing this using XmlMapper in jackson-dataformat-xml like this:

xmlMapper.reader(Student.class).withRootName("prefix:student").readValue(xmlString)

I get the following exception:

java.io.IOException: com.ctc.wstx.exc.WstxParsingException: Undeclared namespace prefix "prefix"
 at [row,col {unknown-source}]: [1,9]
    at com.fasterxml.jackson.dataformat.xml.util.StaxUtil.throwXmlAsIOException(StaxUtil.java:24)
    at com.fasterxml.jackson.dataformat.xml.XmlFactory._createParser(XmlFactory.java:473)
    at com.fasterxml.jackson.dataformat.xml.XmlFactory._createParser(XmlFactory.java:26)
    at com.fasterxml.jackson.core.JsonFactory.createParser(JsonFactory.java:844)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2091)

Caused by: com.ctc.wstx.exc.WstxParsingException: Undeclared namespace prefix "prefix"
 at [row,col {unknown-source}]: [1,9]
    at com.ctc.wstx.sr.StreamScanner.constructWfcException(StreamScanner.java:606)
    at com.ctc.wstx.sr.StreamScanner.throwParseError(StreamScanner.java:479)
    at com.ctc.wstx.sr.InputElementStack.resolveAndValidateElement(InputElementStack.java:507)
    at com.ctc.wstx.sr.BasicStreamReader.handleStartElem(BasicStreamReader.java:2977)
    at com.ctc.wstx.sr.BasicStreamReader.handleRootElem(BasicStreamReader.java:2098)
    at com.ctc.wstx.sr.BasicStreamReader.nextFromProlog(BasicStreamReader.java:2078)
    at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1134)
    at com.fasterxml.jackson.dataformat.xml.XmlFactory._initializeXmlReader(XmlFactory.java:581)
    at com.fasterxml.jackson.dataformat.xml.XmlFactory._createParser(XmlFactory.java:471)
    ... 6 more

What do I need to do for XML deserialization with custom root name ??


Solution

  • Your problem is that XML input is invalid as it is missing the namespace declaration for prefix: if namespace handling is enabled (as it is by most modern XML parsers), Jackson XML module can't do anything about that.

    But as per other answer it is often possible to configure underlying XML parser to disable namespace handling, in which case the whole element name is just considered part of "local name", and no namespace information will be maintained.

    Just make sure to use either Woodstox or Aalto Stax parsers: one in JDK does not support no-namespace mode, I think.