2011-09-21 82 views
5

我刚刚开始使用JAXB从Java对象中创建XML输出。在我的java类中存在一个多态性,这似乎不适用于JAXB。jaxb - 如何从多态类创建XML

下面是我试图处理它的方式,但在输出中我没有预料到field:fieldA或fieldB。

@XmlRootElement(name = "root") 
public class Root { 
    @XmlElement(name = "fieldInRoot") 
    private String fieldInRoot; 
    @XmlElement(name = "child") 
    private BodyResponse child; 
    // + getters and setters 
} 

public abstract class BodyResponse { 
} 

@XmlRootElement(name = "ResponseA") 
public class ResponseA extends BodyResponse { 
    @XmlElement(name = "fieldA") 
    String fieldB; 
    // + getters and setters 
} 

@XmlRootElement(name = "ResponseB") 
public class ResponseB extends BodyResponse { 
    @XmlElement(name = "fieldB") 
    String fieldB; 
    // + getters and setters 
} 

在我开始发明一些复杂的继承之前,有没有什么好的方法来做到这一点?

回答

7

您的使用情况下,你可能会想利用@XmlElementRefs,这相当于取代基的概念XML模式:

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Root { 
    @XmlElement 
    private String fieldInRoot; 
    @XmlElementRef 
    private BodyResponse child; 
    // + getters and setters 
} 

您也可以利用xsi:type属性作为继承指标:

的EclipseLink JAXB(MOXY)还具有@XmlDescriminatorNode/@XmlDescriminatorValue延伸:

+0

是的,这是完美的作品。感谢这篇文章和参考你的博客。 – smas

1
@XmlRootElement(name = "root") 
public class Root { 
    .... 

    @XmlElements({ 
     @XmlElement(type = ResponseA.class, name = "ResponseA"), 
     @XmlElement(type = ResponseB.class, name = "ResponseB")}) 
    private BodyResponse child; 

} 

也许你需要在你的Response类的@XmlType(name = "ResponseX")

+2

在JAXB的'@ XmlElements'映射的存在是为了表示选择结构(HTTP: //blog.bdoughan.com/2010/10/jaxb-and-xsd-choice-xmlelements.html)。对于这个继承用例,替换组的概念更适合,并用'@ XmlElementRefs'(http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-substitution.html)进行映射。对, –