我正在尝试将休息调用返回的Xml解组为POJO。但是,一次调用可以返回具有不同根元素的不同类型的文档,例如
<obj1> ... </obj1>
<obj2> ... </obj2>
我使用通用函数解组:
private <T> T unmarshal(String xml, Class<T> clazz) {
JAXBContext jc = JAXBContext.newInstance(clazz);
return clazz.cast(jc.createUnmarshaller().unmarshal(new StringReader(xml));
}
我已创建为每个不同的根分开类,但我不知道如何检查根元素类型,然后使用正确的类型调用我的unmarshall函数?
if rootElement.equals("obj1")
Obj1 obj = unmarshal(xml, Obj1.class)
else if rootElement.equals("obj2")
Obj2 obj = unmarshal(xml, Obj2.class)
有没有办法使用JaxB对根元素进行这种条件检查?
答案 0 :(得分:0)
是的,这是可能的。
@XmlRootElement
声明每个可能的根类。使用以下所有可能的根类创建JAXBContext。
JAXBContext jc = JAXBContext.newInstance(Class...)
然后,
Object obj = unmarshal(xml);
if(obj instanceof Root1) {
// cast to Root1 object
}
else obj instanceof Root2) {
// cast to Root2 object
}
答案 1 :(得分:0)
我不知道是否有更好的方法可以做到这一点,但我找不到一个。 为了解决这个问题,我创建了一个包含两种根元素类型的对象:
@Data
public class compositionObject {
private Obj1 obj1;
private Obj2 obj2;
public compositionObject(final Object obj) {
if(obj instanceof Obj1) {
this.obj1 = obj1;
} else if(obj instanceof Obj2) {
this.obj2 = obj2;
} else {
throw new IllegalArgumentExcepion("not supported");
}
}
以半通用的方式解组:
private Object unmarshal(String xml, Class<?>... clazzes) {
JAXBContext jc = JAXBContext.newInstance(clazzes);
return clazz.cast(jc.createUnmarshaller().unmarshal(new StringReader(xml));
}
将@XmlRegistry
与@XmlElementDecl
一起使用并不会给我预期的行为,因为它会返回JAXBElement<Obj1>
而不是JAXBElement<CompositionObject>
。以下不起作用:
private final static QName OBJ1_QNAME = new QName("", "obj1");
private final static QName COMP_OBJ_QNAME = new QName("", "compositionobj");
@XmlElementDecl(namespace = "", name = "obj1")
public JAXBElement<CompositionObject> createObj1(final Obj1 value) {
final CompositionObject compObj = new CompositionObject();
comPbj.setObj1(value);
return new JAXBElement<CompositionObject>(COMP_OBJ_QNAME, CompositionObject.class, null, value);
}
问题:@XmlRegistry - how does it work?回答为什么不能以这种方式使用@XmlRegistry。