我遇到了解决嵌套xml问题的问题。有人可以告诉我,如果我遗失了什么
body
标记可以包含任何Jaxb anotated obj
我是否必须创建一个自定义适配器来编组/解组这样的xml?
输入XML
<?xml version="1.0" encoding="UTF-8"?>
<serviceRq xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="serviceRq">
<body>
<createRq>
<id>1234</id>
</createRq>
</body>
</serviceRq>
我的Jaxb注释类是:
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "serviceRq")
public class ServiceRq{
private Object body;
<!-- getters and setters omitted-->
}
这里,body可以是任何jaxb注释对象,在本例中是CreateRq。
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "createRq")
public class CreateRq{
private String id;
<!-- getters and setters omitted-->
}
我正在寻找一种通用方法来支持输入xml体中任何带有Jaxb注释的对象。
答案 0 :(得分:6)
您可以使用@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<Body, Object>{
@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);
}
}
了解更多信息
答案 1 :(得分:2)
您可以使用@XmlAnyElement(lax=true)
和EclipseLink JAXB (MOXy)中的@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
了解更多信息