如何链接未在JAXBContext中使用的对象的XmlElements?

时间:2016-04-06 12:43:36

标签: java xml jaxb

在创建Marsaller时,是否有任何方法可以链接或引用JAXBContext中未使用的类的XmlElements?

我使用Jersey将JAXB注释对象转换为XML文件。

这是我的设置。所有课程都在同一个包中。

对于Marsaller,我使用B,C或D类

null

每个案件的Marsaller都是

@XmlAccessorType(XmlAccessType.NONE)
class A {
    private Foo foo;

    public SomeObject getSomeObjetct() {
        return foo.getSomeObjetct();
    }


    protected setFooBehavior(Foo f) {
        this.foo = f;
    }



    /* From this point the XmlElements are commond to all subclasses
     * and no other special manipulation take place.
     */  

    @XmlElement(...)
    ...someGetterMethod(){}

    @XmlElement(...)
    ...someOtherGetterMethod(){}

    @XmlElement(...)
    ...someThirdGetterMethod(){}

    ...
    ...


}

@XmlRootElement(name = "B")
class B extends A{
    setFooBehavior(new FooA());
}

@XmlRootElement(name = "C")
class C extends A{
    setFooBehavior(new FooA());
}

@XmlRootElement(name = "D")
class D extends A{
    setFooBehavior(new FooB());
}

class FooA {
    SomeObject someObject;

    @XmlElement(name = "FooA", required = true)
    public SomeObject getSomeObjetct() {
        return getSomeObjetct();
    }

    public setSomeObject(SomeObject someObject;) {
        this.someObject = SomeObject someObject;;
    }
}

class FooB {
    SomeObject someObject;

    @XmlElement(name = "FooB", required = true)
    public SomeObject getSomeObjetct() {
        return getSomeObjetct();
    }

    public setSomeObject(SomeObject someObject;) {
        this.someObject = SomeObject someObject;;
    }
}

最后,我希望得到以下xml结果

对于C类

JAXBContext jaxbContext = JAXBContext.newInstance(C.class); //or B.class or D.class
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

对于D级

<C>
    <FooA>someObjectValue</FooA>
</C>

我现在得到的输出是

<D>
    <FooB>someObjectValue</FooB>
</D>

<C>
    <someObject>someObjectValue</someObject>
<C>

分别

1 个答案:

答案 0 :(得分:0)

你提到someObject需要在D中进行特殊处理。你还有一个Foo实例吗?你能做到:

public class A {

    @XmlElementRef
    public Foo getFoo() {
        return foo;
    }

    @XmlTransient
    public SomeObject getSomeObject() {
        return foo.getSomeObject();
    }

}

更新:鉴于您无法公开Foo,那么信息将必须存储在其他一些机制中。以下解决方案并不是很好,但可能有用:

public class A {

    private Class<?> fooType;

    //protected should be enough for JAX-B and will
    //hide the method from the rest of your code.
    @XmlAnyElement
    protected JAXBElement<SomeObject> getSomeObjetctForJaxb() {
        return new JAXBElement<SomeObject>(new QName(fooType.getSimpleName()), SomeObject.class, getSomeObjetct());
    }

}

您是否还需要解组XML?如果是这样,你将需要一个接收JAXBElement<SomeObject>的setter,并且必须根据元素的名称适当地创建Foo。