2011-02-16 66 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>