2011-09-21 57 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)進行映射。對, –