XSD架构和JAXB类中的多态性

时间:2011-02-16 18:06:30

标签: xsd jaxb

我有一个像这样的xml:

<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() {
        ...
    }

}

理想情况下,我想要的是一种定义所有其他XSD类型扩展的通用基类型的方法。从XSD架构生成的Jaxb类应该有一个返回通用任务列表的方法。这样可以很容易地将新任务添加到待办事项列表中:

public class Todo {

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

}

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

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

为了生成上述Java类,XSD架构应该是什么样的?

4 个答案:

答案 0 :(得分:19)

我在Blaise 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()。

答案 1 :(得分:6)

xsd:choice对应于@XmlElements注释。您可以将此注释直接应用于所需的对象模型。

有关详细信息,请参阅:

答案 2 :(得分:0)

在架构中使用xs:extension,您将在架构中定义继承(扩展)JAXB类。

答案 3 :(得分: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>