XML Schema - choice元素中的maxOccurs

时间:2013-11-08 16:27:43

标签: xsd

我有以下架构声明:

<element name="container">
  <complexType>
    <choice minOccurs="0" maxOccurs="unbounded">
      <element name="action" minOccurs="0" maxOccurs="1" />
      <element name="query" minOccurs="0" maxOccurs="unbounded" />
      <element name="validator" minOccurs="0" maxOccurs="unbounded" />
    </choice>
  </complexType>
</element>

我基本上希望<container>包含所需数量的<query><validator>元素,但只包含一个<action>元素(可能没有)。

据我所知,我无法在<choice>上放置maxOccurs,因为从技术上讲,该选择可以无限次地进行(由于查询和验证器上没有显示)。

但是,这个XML在Eclipse中被认为是有效的(这可能只是Eclipse验证中的一个问题,尽管所有其他位工作正常)

<container>
  <action id="action1" name="action1" />
  <action id="action2" name="action2" />
  <query id="query1" />
  <validator id="testValidator" />
</container>

不确定我是否遗漏了一些明显的东西。

1 个答案:

答案 0 :(得分:12)

您当前的模型定义了(a)一个action元素或无元素,(b)零个或多个query元素或(c)零个或多个validator元素之间的选择,然后允许该选择重复零次或多次。因此它相当于

<choice minOccurs="0" maxOccurs="unbounded">
  <element name="action"/>
  <element name="query"/>
  <element name="validator"/>
</choice>

允许任何零个或多个元素的序列,每个元素都是actionqueryvalidator元素。

使用sequence代替choice可以满足您制定的要求:

<sequence>
  <element name="action" minOccurs="0" maxOccurs="1" />
  <element name="query" minOccurs="0" maxOccurs="unbounded" />
  <element name="validator" minOccurs="0" maxOccurs="unbounded" />
</sequence>

有时,不同类型的元素出现的顺序传达信息,因此有必要允许它们混合。在这种情况下,问题类似于以下reqular-expression问题:编写一个正则表达式,定义由'a','q'和'v'组成的字符串集,其中'a'最多出现一次。一个明显的正则表达式是(q|v)*(a(q|v)?)。类似的XSD模型组是:

<sequence>
  <choice minOccurs="0" maxOccurs="unbounded">
    <element ref="query"/>
    <element ref="validator"/>
  </choice>
  <sequence minOccurs="0">
    <element name="action"/>
    <choice minOccurs="0" maxOccurs="unbounded">
      <element ref="query"/>
      <element ref="validator"/>
    </choice>
  </sequence>
</sequence>

(我已经从局部元素声明更改为元素引用,以避免每次都声明queryvalidator两次。)

在XSD 1.1中,应该可以与all组获得相同的效果:

<all>
  <element name="action" minOccurs="0" maxOccurs="1" />
  <element name="query" minOccurs="0" maxOccurs="unbounded" />
  <element name="validator" minOccurs="0" maxOccurs="unbounded" />
</all>