问题
I cannot achieve to unmarshall an XML without knowing the root element. eg.
<foo>
<bar/>
</foo>
or
<bar>
<bar/>
</bar>
etc...
I want to map the unmarshalling result on a class like :
// @XmlRootElement ??
public class Container
implements Serializable
{
private Bar bar;
}
I am always required to fix the @XmlRootElement
.
I searched how to set the @XmlRootElement at runtime without success. Any idea?
I am in Spring Batch context and I can use the unmarshaller of my choice.
Note : I cannot use @XmlElementDecl
or an ObjectFactory
as shown here because I don't know the name of the possibles root names.
回答1:
Adapted his approach: https://stackoverflow.com/a/33824472/181336
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.transform.stream.StreamSource;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.Serializable;
public class Test {
@XmlAccessorType(XmlAccessType.PROPERTY)
public static class Bar {
private String name;
public String getName() {
return name;
}
@XmlElement
public void setName(String name) {
this.name = name;
}
}
@XmlAccessorType(XmlAccessType.PROPERTY)
public static class Container implements Serializable {
private Bar bar;
public Bar getBar() {
return bar;
}
@XmlElement
public void setBar(Bar bar) {
this.bar = bar;
}
}
public static void main(String[] args) throws Exception {
JAXBContext jaxbContext = JAXBContext.newInstance(Container.class);
String xml = "<foo><bar><name>Barry</name></bar></foo>";
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
InputStream is = new ByteArrayInputStream(xml.getBytes());
JAXBElement<Container> barWrapperElement = unmarshaller.unmarshal(new StreamSource(is), Container.class);
Container container = barWrapperElement.getValue();
System.out.println(container.getBar().getName());
}
}
It works!
回答2:
Which ever XML your passing does have a root elements, xml which you mentioned have two file
<foo>
<bar/>
</foo>
or
<bar>
<bar/>
so here you have two root names foo or bar so create two classes for each if which ever root name it will call that class
来源:https://stackoverflow.com/questions/41545564/jaxb-unmarshall-with-an-unknown-xmlrootelement