Jaxb unmarshall取决于根元素

时间:2017-01-26 23:53:17

标签: xml xml-parsing jaxb

我正在尝试将休息调用返回的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对根元素进行这种条件检查?

2 个答案:

答案 0 :(得分:0)

是的,这是可能的。

  1. 使用@XmlRootElement声明每个可能的根类。
  2. 使用以下所有可能的根类创建JAXBContext。

    JAXBContext jc = JAXBContext.newInstance(Class...)

  3. 然后,

    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。