【问题标题】:XML Schema (XSD) - How to specify parent element to contain at least one child element?XML Schema (XSD) - 如何指定父元素至少包含一个子元素?
【发布时间】:2011-01-30 05:48:39
【问题描述】:

我有一个 XML 模式 (XSD),它将一个元素定义为必需的(称为父元素);假设这个父元素有五个子元素,它们都可以是可选的,但至少必须出现一个子元素。

如何在 xsd 中指定这个?

澄清:孩子是不同的元素和可选的。 例如。

<Parent>
   <Child1>contents are different to other siblings and arbitrary</Child1>
   <Child2>can be text, a simple element, or another complex element</Child2>
   <Child3>etc.. etc</Child3> 
</Parent>

<xs:complexType name="Parent">
  <xs:sequence>
    <xs:element minOccurs="0" name="Child1" type="xs:string"/>
    <xs:element minOccurs="0" name="Child2" />
    <xs:element minOccurs="0" name="Child3" />
  </xs:sequence>
</xs:complexType>

即使每个孩子都是可选的,但父母至少需要有一个孩子。

【问题讨论】:

  • 在查看了答案(以及大量谷歌搜索)之后,似乎 xsd 中没有简单的构造来指定这一点;麻烦多于其价值,我选择让验证软件强制执行附加规则(例如必须至少有一个孩子)。

标签: xml xsd schema


【解决方案1】:
<xs:complexType name="Parent">
  <xs:choice maxOccurs="unbounded">
    <xs:element name="Child1" type="xs:string"/>
    <xs:element name="Child2" />
    <xs:element name="Child3" />
  </xs:sequence>
</xs:complexType>

选择maxOccurs="unbounded"(默认minOccurs=1 => 至少一个孩子)

【讨论】:

    【解决方案2】:

    使用断言(我认为它仅在 XSD 1.1 中可用)可以执行以下操作:

    <xs:element name="Parent">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Child1" type="xs:string" minOccurs="0"/>
                <xs:element name="Child2" minOccurs="0"/>
                <xs:element name="Child3" minOccurs="0"/>
            </xs:sequence>
            <xs:assert test="count(*)>=1"/>
        </xs:complexType>
    </xs:element>
    

    【讨论】:

      【解决方案3】:

      总是有直接的方法:

      <xs:complexType name="Parent">
        <xs:choice>
          <xs:sequence>
            <xs:element name="Child1"/>
            <xs:element name="Child2" minOccurs="0"/>
            <xs:element name="Child3" minOccurs="0"/>
          </xs:sequence>
          <xs:sequence>
            <xs:element name="Child2"/>
            <xs:element name="Child3" minOccurs="0"/>
          </xs:sequence>
          <xs:sequence>
            <xs:element name="Child3"/>
          </xs:sequence>
        </xs:choice>
      </xs:complexType>
      

      【讨论】:

      • 直接方法可能会奏效;但是对于很多子元素来说太麻烦了。
      • 当您将 JAXB 转换为 Java 类时,它会产生错误的结果
      【解决方案4】:

      您可以创建一个包含所有子元素的替换组。为此,您使用minOccurs 属性来指定该组中的至少一个元素必须出现在文档中。

      【讨论】:

      • 不要认为这会起作用;替换组元素必须以某种方式相互关联或派生;正如我的问题中提到的那样,我的元素是完全独立的。
      【解决方案5】:

      使用 minOccurs,例如

      <xsd:complexType name="Parent">
        <xsd:sequence>
          <xsd:element minOccurs="1" maxOccurs="5" name="Child" type="q10:string"/>
          </xsd:sequence>
      </xsd:complexType>
      

      【讨论】:

      • 不是我想要的。请查看更新的问题,希望能阐明意图。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-08
      • 2023-03-20
      • 1970-01-01
      • 1970-01-01
      • 2010-09-15
      • 1970-01-01
      相关资源
      最近更新 更多