控制嵌套元素的maxOccurs,而不强制执行序列

时间:2012-09-18 02:10:06

标签: xml xsd xsd-1.0

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

我有一个 parent1 元素,可以包含以下子元素 child1 child2 child3

  • parent1 可以包含0-1 child1
  • parent1 可以有<1> child2
  • parent1 可以为0 - 无界 child3

项目的顺序并不重要。 E.g。

<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。我也尝试使用选择maxOccurs来替换序列,但这不会限制child1child2元素的数量{ {1}}。

编辑:这适用于XSD v1.0

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

3 个答案:

答案 0 :(得分:1)

正如Hantin所说,这在XSD 1.0中是混乱的。

在XSD 1.1中,你可以在xs:all模型组的粒子上有一个maxOccurs属性,这样你的问题就解决了。 XSD 1.1目前在Saxon和Xerces中实施。

答案 1 :(得分:1)

虽然正如迈克尔凯所指出的那样,但这并不是特别难,但是它很混乱而且令人失望。将Jeffrey Hantin的示例转换为DTD表示法以简明扼要并使用c1c2c3(再次简化)作为元素名称,解决方案是

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

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

答案 2 :(得分:0)

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

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

minOccurs="0"