XSD多态性不适用于JAXP?

时间:2015-01-22 14:08:31

标签: java xml xsd

我有这样的XML:

<members>
  <member>
    <name>john</name>
    <properties>
      <age>20</age>
      <address>20</address>
   </properties>
  </member>
  <member>
    <name>kayla</name>
    <properties>
      <gender>female</gender>
      <address>20</address>
   </properties>
  </member>
</members>

这里会有几个成员节点,它们共享一个<name>节点和一个properties节点。但是,properties中的元素不同,age+addressgender+address都是有效的选择。

我试着像这样写一个XSD:

    <?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="members" type="membersType"/>
  <xs:complexType name="membersType">
    <xs:sequence>
      <xs:element type="memberType" name="member" maxOccurs="unbounded" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="memberType">
    <xs:sequence>
      <xs:element name="name" type="xs:string"/>
      <xs:element type="propertiesType" name="properties"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="propertiesType">
    <xs:sequence>
      <xs:element type="xs:string" name="address"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="propertiesTypeA">
    <xs:complexContent>
      <xs:extension base="propertiesType">
        <xs:sequence>
          <xs:element type="xs:string" name="age" minOccurs="0"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="propertiesTypeB">
    <xs:complexContent>
      <xs:extension base="propertiesType">
        <xs:sequence>
          <xs:element type="xs:string" name="gender" minOccurs="0"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

</xs:schema>

我希望这里可以有类似多态的东西,但是当我使用JAXP进行验证时,这并不起作用。 我还尝试使用group功能,但两组中的address元素相同,因此它仍然不可用。

那么,我应该如何设计XSD?

2 个答案:

答案 0 :(得分:0)

您可以使用以下内容

<complexType name="MemberDTO">
        <complexContent>
            <extension base="tns:MemberEnumValueDTO">
                <sequence />
            </extension>
        </complexContent>
</complexType>

<complexType name="MemberEnumValueDTO">
        <sequence>
            <element name="name" type="tns:NameEnumTextType" minOccurs="1"
                maxOccurs="1" />
        </sequence>
</complexType>

<simpleType name="NameEnumTextType">
        <restriction base="string">
        <enumeration value="john" />
        <enumeration value="kayla" />
        </restriction>
</simpleType>

答案 1 :(得分:0)

您当前的XML架构

使用您的XML Schema,您的XML需要如下所示:

<members xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <member>
    <name>john</name>
    <properties xsi:type="propertiesTypeA">
      <address>20</address>
      <age>20</age>
   </properties>
  </member>
  <member>
    <name>kayla</name>
    <properties xsi:type="propertiesTypeB">
      <address>20</address>
      <gender>female</gender>
   </properties>
  </member>
</members>

请注意以下事项:

  • 首先需要显示继承的属性。
  • 您需要使用xsi:type属性覆盖元素类型作为子类型。

你可能想要的东西

指定&#34;选择&#34;在您的XML Schema中可能更适合您。您将不再需要子类型。

  <xs:complexType name="propertiesType">
    <xs:sequence>
      <xs:choice>
       <xs:element type="xs:string" name="age"/>
       <xs:element type="xs:string" name="gender"/>
      </xs:choice>
      <xs:element type="xs:string" name="address"/>
    </xs:sequence>
  </xs:complexType>