Jaxb complex xml unmarshall
我有问题解组下面的嵌套xml。 有人可以告诉我,如果我遗失了什么。
body
标签可以包含任何Jaxb anotated obj。
我是否必须创建一个自定义适配器来编组/解组这样的xml?
输入XML
1234
我的Jaxb注释类是:
@XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "serviceRq") public class ServiceRq{ private Object body; }
这里,body可以是任何jaxb注释对象,在本例中是其CreateRq。
@XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "createRq") public class CreateRq{ private String id; }
我正在寻找一种通用的方法来支持输入xml体中的任何Jaxb带注释的对象。
您可以使用@XmlAnyElement(lax=true)
和XmlAdapter
来处理此用例:
ServiceRq
import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "serviceRq") public class ServiceRq{ @XmlJavaTypeAdapter(value=BodyAdapter.class) private Object body; // getters and setters omitted }
BodyAdapter
import javax.xml.bind.annotation.adapters.XmlAdapter; public class BodyAdapter extends XmlAdapter{ @Override public Object unmarshal(Body v) throws Exception { return v.getValue(); } @Override public Body marshal(Object v) throws Exception { Body body = new Body(); body.setValue(v); return body; } }
身体
import javax.xml.bind.annotation.XmlAnyElement; public class Body { private Object value; @XmlAnyElement(lax=true) public Object getValue() { return value; } public void setValue(Object value) { this.value = value; } }
CreateRq
import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "createRq") public class CreateRq{ private String id; // getters and setters omitted }
演示
import java.io.File; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(ServiceRq.class); System.out.println(jc); Unmarshaller unmarshaller = jc.createUnmarshaller(); ServiceRq serviceRq = (ServiceRq) unmarshaller.unmarshal(new File("input.xml")); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(serviceRq, System.out); } }
了解更多信息
您可以在EclipseLink JAXB(MOXy)中使用@XmlAnyElement(lax=true)
和@XmlPath
扩展来处理这个用例(注意:我是MOXy的主管)。 对于适用于任何JAXB实现( Metro , MOXy , JaxMe等)的方法,请参阅: Jaxb complex xml unmarshall 。
ServiceRq
import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAnyElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; import org.eclipse.persistence.oxm.annotations.XmlPath; @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "serviceRq") public class ServiceRq{ @XmlPath("body/createRq") @XmlAnyElement(lax=true) private Object body; // getters and setters omitted }
CreateRq
import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "createRq") public class CreateRq{ private String id; // getters and setters omitted }
演示
import java.io.File; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(ServiceRq.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); ServiceRq serviceRq = (ServiceRq) unmarshaller.unmarshal(new File("input.xml")); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(serviceRq, System.out); } }
jaxb.properties
要将MOXy用作JAXB提供程序,必须在与域模型相同的包中包含名为jaxb.properties的文件,并使用以下条目:
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
了解更多信息
- http://bdoughan.blogspot.com/2010/08/using-xmlanyelement-to-build-generic.html
- http://bdoughan.blogspot.com/2011/05/specifying-eclipselink-moxy-as-your.html
- http://bdoughan.blogspot.com/2010/09/xpath-based-mapping-geocode-example.html
- http://bdoughan.blogspot.com/2011/03/map-to-element-based-on-attribute-value.html