9

我有以下模式声明:

<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>

我基本上希望 a<container>包含尽可能多的<query>or<validator>元素,但只有一个<action>元素(可能没有)。

据我所知,我不能设置 maxOccurs ,<choice>因为从技术上讲,选择可以无限次进行(由于查询和验证器的不确定性)。

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

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

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

4

1 回答 1

15

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

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

它允许任何零个或多个元素的序列,每个元素是一个action、一个query或一个validator元素。

您制定的要求可以通过使用来满足,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>

有时,不同种类的元素出现的顺序传达了信息,因此有必要让它们混合在一起。在这种情况下,问题类似于以下正则表达式问题:编写一个正则表达式,定义由“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>
于 2013-11-09T00:55:04.710 回答