问题
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