2011-02-16 91 views
22

我有一個這樣的XML:多態性XSD架構和JAXB類

<todo> 
    <doLaundry cost="1"/> 
    <washCar cost="10"/> 
    <tidyBedroom cost="0" experiencePoints="5000"/> 
</todo> 

而且XSD架構是:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:complexType name="todo"> 
     <xs:sequence> 
      <xs:choice maxOccurs="unbounded"> 
       <xs:element name="doLaundry" type="doLaundry" /> 
       <xs:element name="washCar" type="washCar" /> 
       <xs:element name="tidyBedroom" type="tidyBedroom" /> 
      </xs:choice> 
     </xs:sequence> 
    </xs:complexType> 

    <xs:complexType name="doLaundry"> 
     <xs:attribute name="cost" type="xs:int" /> 
    </xs:complexType> 

    <xs:complexType name="washCar"> 
     <xs:attribute name="cost" type="xs:int" /> 
    </xs:complexType> 

    <xs:complexType name="tidyBedroom"> 
     <xs:attribute name="cost" type="xs:int" /> 
     <xs:attribute name="experiencePoints" type="xs:int" /> 
    </xs:complexType> 
</xs:schema> 

當我通過JAXB處理這個模式,我收到了類的方法是這樣的:

public class Todo { 

    public List<Object> getDoLaundryOrWashCarOrTidyBedroom() { 
     ... 
    } 

} 

理想情況下,我想要的是一種方法來定義一個泛型基類型的所有其他X SD類型擴展。從XSD模式生成的Jaxb類應該有一個返回一般任務列表的方法。這將使它很容易添加新任務的待辦事項列表:

public class Todo { 

    public List<Task> getTasks() { 
     ... 
    } 

} 

public abstract class Task { 
    public int getCost() { 
     ... 
    } 
} 

public class TidyBedroom extends Task { 
    public int getExperiencePoints() { 
     ... 
    } 
} 

又該XSD架構的樣子,以產生上述的Java類?

回答

17

我發現布萊斯Doughan的文章的幫助這裏的答案:http://bdoughan.blogspot.com/2010/11/jaxb-and-inheritance-using-xsitype.html

此架構:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:complexType name="todo"> 
     <xs:sequence> 
      <xs:choice maxOccurs="unbounded"> 
       <xs:element name="doLaundry" type="doLaundry" /> 
       <xs:element name="washCar" type="washCar" /> 
       <xs:element name="tidyBedroom" type="tidyBedroom" /> 
      </xs:choice> 
     </xs:sequence> 
    </xs:complexType> 

    <xs:complexType abstract="true" name="Task"> 
     <xs:attribute name="cost" type="xs:int" use="required" /> 
    </xs:complexType> 

    <xs:complexType name="doLaundry"> 
     <xs:complexContent> 
      <xs:extension base="Task"> 
      </xs:extension> 
     </xs:complexContent> 
    </xs:complexType> 

    <xs:complexType name="washCar"> 
     <xs:complexContent> 
      <xs:extension base="Task"> 
      </xs:extension> 
     </xs:complexContent> 
    </xs:complexType> 

    <xs:complexType name="tidyBedroom"> 
     <xs:complexContent> 
      <xs:extension base="Task"> 
       <xs:attribute name="experiencePoints" type="xs:int" /> 
      </xs:extension> 
     </xs:complexContent> 
    </xs:complexType> 

</xs:schema> 

與綁定文件組合:

<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <jxb:bindings> 
     <jxb:bindings schemaLocation="todo.xsd" node="/xs:schema/xs:complexType[@name='todo']/xs:sequence/xs:choice"> 
      <jxb:property name="Tasks"/> 
     </jxb:bindings> 
    </jxb:bindings> 
</jxb:bindings> 

將提供抽象和繼承類,如我在問題中所述。該綁定文件將把Jaxb的默認方法名稱從getDoLaundryOrWashCarOrTidyBedroom()更改爲getTasks()。

6

xsd:choice對應於@XmlElements註釋。您可以將此註釋直接應用於所需的對象模型。

欲瞭解更多信息,請參閱:

+0

我覺得我沒有讓我的問題明確地足夠清楚。我從一個XSD模式開始,希望通過JAXB生成Java類。我想知道是否有可能以給出所需Java對象模型的方式構建XSD - 而不是相反。 – 2011-02-17 11:16:50

+0

您可以在XML模式中定義類型之間的繼承關係。看看這個帖子的例子:http://bdoughan.blogspot.com/2010/11/jaxb-and-inheritance-using-xsitype.html – 2011-02-17 11:30:39

0

使用xs:extension在您的架構和您的JAXB類將被繼承(擴展)如您在模式中定義。

0

也許我不是「得」的問題,而是什麼是錯的..

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:complexType name="todo"> 
     <xs:sequence> 
      <xs:choice maxOccurs="unbounded"> 
       <xs:element name="doLaundry" type="task" /> 
       <xs:element name="washCar" type="task" /> 
       <xs:element name="tidyBedroom" type="task" /> 
      </xs:choice> 
     </xs:sequence> 
    </xs:complexType> 


    <xs:complexType name="task"> 
     <xs:attribute name="cost" type="xs:int" /> 
     <xs:attribute name="experiencePoints" type="xs:int" /> 
    </xs:complexType> 
</xs:schema>