1

我希望定义一个强制执行以下规则的 XSD(基于 v1.0)......

我有一个parent1元素,它可以有以下子元素child1 child2child3

  • parent1可以有child1的 0-1
  • parent1可以有child2的0-1
  • parent1可以有 0 - child3的无界

项目的顺序并不重要。例如

<parent1>
  <child3/>
  <child1/>
  <child2/>
  <child3/>
  <child3/>
</parent1>

我已经接近了,但没有雪茄。我能得到的最接近的是执行最小值和最大值,但执行顺序。

<xsd:element name="parent1" minOccurs="0" maxOccurs="unbounded">
  <xsd:complexType>
    <xsd:sequence>
      <xsd:element name="child1" minOccurs="0" maxOccurs="1"/>
      <xsd:element name="child2" minOccurs="0" maxOccurs="1" />
      <xsd:element name="child3" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
  </xsd:complexType>
</xsd:element>

我尝试过使用all而不是sequence,但子元素限制maxOccurs为 1。我也尝试过使用selection和 amaxOccurs来替换序列,但这并不限制您可以在下面拥有多少个元素child1或元素。child2parent1

编辑:这是针对 XSD v1.0

我找到了一个适用于 XSD 1.1的解决方案,但是当您看到它在 Eclipse 之类的支持中有多好时,我会尝试坚持使用1.0

4

3 回答 3

1

正如 Hantin 所说,这在 XSD 1.0 中组合起来很混乱。

在 XSD 1.1 中,您可以在 xs:all 模型组的粒子上设置 maxOccurs 属性,这样您的问题就解决了。XSD 1.1 目前在 Saxon 和 Xerces 中实现。

于 2012-09-18T08:20:31.763 回答
1

这并不是特别难,尽管正如迈克尔凯所指出的那样,它很混乱而且冗长令人失望。为了简洁起见,将 Jeffrey Hantin 的示例转换为 DTD 表示法,并使用c1, c2, 和c3(再次为简洁起见)作为元素名称,解决方案是

(c3*, ((c1, c3*, (c2, c3*)?) | (c2, c3*, (c1, c3*)?))?)

如果子元素的序列传达信息,那么当然,这对所有这些排序的灵活性都很重要。如果序列不传达任何信息,则不需要允许灵活性,通常应该首选 OP 的原始解决方案。

于 2012-09-18T16:43:37.970 回答
0

要在 XML Schema 1.0 中做到这一点,您最终必须将可能的xs:all粒子“展开”到选择序列树中(其中每个选择的每个分支都有一个唯一的非可选的第一个元素)给你这样的东西:

编辑:纠正了我对要求的看法并因此大大减少了冗长。还进行了一些优化以进一步降低冗长性:包含空分支的选择将空分支转换为minOccurs=0选择,如果该转换留下只有一个分支的选择,则选择本身被省略并minOccurs="0"转移到其唯一的孩子。

<xs:sequence>
  <xs:element name="nationality" minOccurs="0" maxOccurs="unbounded" />
  <xs:choice minOccurs="0">
    <xs:sequence>
      <xs:element name="name" />
      <xs:element name="nationality" minOccurs="0" maxOccurs="unbounded" />
      <xs:sequence minOccurs="0">
        <xs:element name="email" />
        <xs:element name="nationality" minOccurs="0" maxOccurs="unbounded" />
      </xs:sequence>
    </xs:sequence>
    <xs:sequence>
      <xs:element name="email">
      <xs:element name="nationality" minOccurs="0" maxOccurs="unbounded" />
      <xs:sequence minOccurs="0">
        <xs:element name="name" />
        <xs:element name="nationality" minOccurs="0" maxOccurs="unbounded" />
      </xs:sequence>
    </xs:sequence>
  </xs:choice>
</xs:sequence>
于 2012-09-18T03:16:57.317 回答