Xml Jaxb解组取决于根元素

Xml Jaxb解组取决于根元素,xml,xml-parsing,jaxb,Xml,Xml Parsing,Jaxb,我试图将rest调用返回的Xml解组到POJO中。但是,一个调用可以返回具有不同根元素的不同类型的文档,例如 <obj1> ... </obj1> <obj2> ... </obj2> 有没有一种方法可以使用JaxB对根元素进行条件检查 是的,这是可能的 用@XmlRootElement声明每个可能的根类 使用所有可能的根类创建JAXBContext,如下所示 JAXBContext jc=JAXBContext.newInstance(类…)

我试图将rest调用返回的Xml解组到POJO中。但是,一个调用可以返回具有不同根元素的不同类型的文档,例如

<obj1> ... </obj1>
<obj2> ... </obj2>
有没有一种方法可以使用JaxB对根元素进行条件检查

是的,这是可能的

  • @XmlRootElement
    声明每个可能的根类
  • 使用所有可能的根类创建JAXBContext,如下所示

    JAXBContext jc=JAXBContext.newInstance(类…)

  • 那么

    objectobj=unmarshal(xml);
    if(根1的obj实例){
    //强制转换到Root1对象
    }
    else obj实例(根目录2){
    //强制转换到Root2对象
    }


  • 我不知道是否有更好的方法,但我没有找到。 为了解决这个问题,我创建了一个包含两种类型根元素的对象:

    @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不能以这种方式使用

    @XmlRootElement
    本身足以在解组后获得正确的对象实例。我认为问题在于您没有将它们作为
    @XmlRootElement
    来处理。也许您可以详细解释为什么不能使用我的答案中上面的第3点直接强制转换到根元素对象?Obj1和Obj2模型类都用“@XmlRootElement”注释。我想问题陈述有点模棱两可。我想编写一个自定义的解析逻辑,这样它就可以接受多个'@XmlRootElement',并将它们转换为单个对象。我之所以想这样做,是因为我对外部REST服务的调用可以为同一个调用返回不同类型的对象。
    @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));
    }
    
    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);
    }