XSD - 扩展XSD,然后添加自定义嵌套元素

时间:2018-05-24 02:00:15

标签: xml xsd

我正在尝试为2种不同的XML消息设计XSD:

<message>
    <common1>value1</common1>
    <common2>value2</common2>
    <common3>
        <unique1>hello</unique1>
    </common3>
    <common4>
        <unique2>bye</unique2>
    </common4>
</message>

<message>
    <common1>value1</common1>
    <common2>value2</common2>
    <common3>
        <unique3>hey</unique3>
    </common3>
    <common4>
        <unique4>goodbye</unique4>
    </common4>
</message>

因为我看到他们有共同的元素,只有独特的嵌套元素,我想创建一个xsd可以扩展的通用父级,所以我可以担心独特的字段,但我仍然不知道如何在父级别中定义common3或4,所以我已经在孩子的xsds上定义了它,我认为这是错误的,任何人都可以验证并对此有所了解吗?

parent.xsd:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="message">
      <xs:complexType>
        <xs:sequence>
          <xs:element name="common1" type="xs:string"/>
          <xs:element name="common2" type="xs:string"/>
        </xs:sequence>
      </xs:complexType>
    </xs:element>
</xs:schema>

child1.xsd:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:include schemaLocation="parent.xsd"/>
    <xs:complexType>
        <xs:complexContent>
            <xs:extension base="message">
                <xs:sequence>
                    <xs:element name="common3" type="common3Type" />
                    <xs:element name="common4" type="common4Type" />
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
    <xs:complexType name="common3Type">
      <xs:sequence>
          <xs:element name="unique1" type="xs:string"/>
      </xs:sequence>
    </xs:complexType>
    <xs:complexType name="common4Type">
      <xs:sequence>
          <xs:element name="unique2" type="xs:string"/>
      </xs:sequence>
    </xs:complexType>
</xs:schema>

child2.xsd:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:include schemaLocation="parent.xsd"/>
    <xs:complexType>
        <xs:complexContent>
            <xs:extension base="message">
                <xs:sequence>
                    <xs:element name="common3" type="common3Type" />
                    <xs:element name="common4" type="common4Type" />
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
    <xs:complexType name="common3Type">
      <xs:sequence>
          <xs:element name="unique3" type="xs:string"/>
      </xs:sequence>
    </xs:complexType>
    <xs:complexType name="common4Type">
      <xs:sequence>
          <xs:element name="unique4" type="xs:string"/>
      </xs:sequence>
    </xs:complexType>
</xs:schema>

1 个答案:

答案 0 :(得分:1)

您可以对XML Schema使用扩展名限制,这样您就可以在超类型中拥有common3common4的通用定义,然后为child1约束这些定义}和child2消息子类型分别为:

<!-- message.xsd -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:complexType name="message">
    <xs:sequence>
      <xs:element name="common1" type="xs:string"/>
      <xs:element name="common2" type="xs:string"/>
      <xs:element name="common3" type="xs:anyType" minOccurs="0"/>
      <xs:element name="common4" type="xs:anyType" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="message-subtype-a">
    <xs:complexContent>
      <xs:restriction base="message">
        <xs:sequence>
          <xs:element name="common1" type="xs:string"/>
          <xs:element name="common2" type="xs:string"/>
          <xs:element name="common3" type="common3-subtype-a" minOccurs="1"/>
          <xs:element name="common4" type="common4-subtype-a" minOccurs="1"/>
        </xs:sequence>
      </xs:restriction>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="message-subtype-b">
    <xs:complexContent>
      <xs:restriction base="message">
        <xs:sequence>
          <xs:element name="common1" type="xs:string"/>
          <xs:element name="common2" type="xs:string"/>
          <xs:element name="common3" type="common3-subtype-b" minOccurs="1"/>
          <xs:element name="common4" type="common4-subtype-b" minOccurs="1"/>
        </xs:sequence>
      </xs:restriction>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="common3-subtype-a">
    <xs:sequence>
      <xs:element name="unique1" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="common4-subtype-a">
    <xs:sequence>
      <xs:element name="unique2" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="common3-subtype-b">
    <xs:sequence>
      <xs:element name="unique3" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="common4-subtype-b">
    <xs:sequence>
      <xs:element name="unique4" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>

</xs:schema>

注意我已将所有类型定义放在单个模式文件中。对于声明元素,您仍然需要两个模式用于相应的消息子类型,因为您希望消息都包含在message元素中:

<!-- message-a.xsd -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:include schemaLocation="message.xsd"/>
  <xs:element name="message" type="message-subtype-a"/>
</xs:schema>

<!-- message-b.xsd -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:include schemaLocation="message.xsd"/>
  <xs:element name="message" type="message-subtype-b"/>
</xs:schema>

当使用按限制派生时,您必须为每个单独的子类型重复内容模型,如XML Schema规范的作者之一在XML Schema Restriction for Complex types : Complete Redefinition?中所述。