JAXB: partial unmarshalling returns empty domain object

穿精又带淫゛_ 提交于 2019-12-11 01:29:07

问题


I'm trying to unmarshal a (well-formed) part of a xml string using the "partial jaxb unmarshaling" technique, described in the answer of this question.

For this I'm using a subset of a JAXB domain models (which have been created by xjc) of the corresponding XML schema. This subset corresponds exactly to the part xml string which the XMLStreamReader processes.

After ensuring that the XMLStreamReader position is correct (which is in fact the first element), I'm invoking

 Unmarshaller unmarshaller = JAXBContext.newInstance(jaxbModelClass)
          .createUnmarshaller();

 return unmarshaller.unmarshal(xsr, jaxbModelClass).getValue();

This is done without any exception and the returned object is indeed an instance of jaxbModelClass, however it's not containing any child elements (all are set to null).

What is the cause of this?


回答1:


Below is an example of how you can handle this use case.

XML

Below is the XML document we will use. The partial document we will unmarshal starts at the bar element. It doesn't matter if the class is created by hand or generated from an XML Schema.

<?xml version="1.0" encoding="UTF-8"?>
<foo xmlns="http://www.example.com">
    <bar>
        <baz>Hello World</baz>
    </bar>
</foo>

Java Model

Bar

This is the class we will unmarshal. Note that it doesn't have an @XmlRootElement annotation.

package forum22818252;

public class Bar {

    private String baz;

    public String getBaz() {
        return baz;
    }

    public void setBaz(String baz) {
        this.baz = baz;
    }

}

package-info

Since our XML document is namespace qualified we will use the package level @XmlSchema annotation (see: http://blog.bdoughan.com/2010/08/jaxb-namespaces.html).

@XmlSchema(
    namespace = "http://www.example.com",
    elementFormDefault = XmlNsForm.QUALIFIED)
package forum22818252;

import javax.xml.bind.annotation.*;

Demo Code

Demo

Below we will parse the document with a StAX XMLStreamReader. Then we advance the XMLStreamReader to the local root we wish to unmarshal. And finally since our class does not have a root element associated with it we will use an unmarshal method that takes a Class parameter.

package forum22818252;

import javax.xml.bind.*;
import javax.xml.stream.*;
import javax.xml.transform.stream.StreamSource;

public class Demo {

    public static void main(String[] args) throws Exception {
        XMLInputFactory xif = XMLInputFactory.newFactory();
        StreamSource source = new StreamSource("src/forum22818252/input.xml");
        XMLStreamReader xsr = xif.createXMLStreamReader(source);
        while(!(xsr.isStartElement() && "bar".equals(xsr.getLocalName()))) {
            xsr.next();
        }

        JAXBContext jc = JAXBContext.newInstance(Bar.class);
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Bar bar = unmarshaller.unmarshal(xsr, Bar.class).getValue();

        System.out.println(bar.getBaz());
    }

}

Output

Below is the output from running the demo code.

Hello World


来源:https://stackoverflow.com/questions/22818252/jaxb-partial-unmarshalling-returns-empty-domain-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!