【问题标题】:XSD - Extend XSD then add custom nested elementsXSD - 扩展 XSD 然后添加自定义嵌套元素
【发布时间】:2018-05-24 02:00:15
【问题描述】:

我正在尝试为 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>

【问题讨论】:

标签: xml xsd


【解决方案1】:

您可以对 XML Schema 使用按限制扩展,这样您就可以在超类型中为 common3common4 提供通用定义,然后为您的 child1child2 消息约束这些定义子类型,分别为:

<!-- 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? 中所解释的那样。

【讨论】:

  • 您好,感谢您的回复,对于我们有无限未知版本的common3/4而不是2版本的场景,这是否也可行?如果没有,您还有什么建议?理想的解决方案是希望允许任何 xsd 扩展所有内容,并在 common3 和 common4 下拥有自己独特的子元素,谢谢!
  • 我建议检查 XML Schema wildcards,它们基​​本上是内容模型中的粒子,当出现在该位置时验证 any 元素(或任何声明的元素,或特定命名空间中的任何元素等);见例如。 stackoverflow.com/questions/943659/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-17
  • 1970-01-01
  • 2012-06-24
相关资源
最近更新 更多