Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XML Schema - maxOccurs within choice element

Tags:

xsd

I've got the following schema declaration:

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

I basically want a <container> to include as many <query> or <validator> elements as wanted, but only one <action> element (and possibly none).

As far as I know I can't put a maxOccurs on the <choice> since technically that choice can be made an unlimited number of times (due to the unbouded on query and validator).

However, this XML is considered valid in Eclipse (which may just well be a problem in Eclipse validation, although all the other bits work fine)

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

Not sure if I'm missing something obvious.

like image 270
Khain Avatar asked Nov 08 '13 16:11

Khain


Video Answer


1 Answers

Your current model defines a choice among (a) one action element or none, (b) zero or more query elements, or (c) zero or more validator elements, and then allows that choice to be repeated zero or more times. It is thus equivalent to

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

which allows any sequence of zero or more elements each of which is an action, a query, or a validator element.

The requirements you formulate can be met by using sequence instead of choice:

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

Sometimes the sequence in which the different kinds of elements occur conveys information, and it is therefore necessary to allow them to be intermingled. In that case, the problem is analogous to the following reqular-expression problem: write a regular expression defining the set of strings consisting of 'a', 'q', and 'v', in which 'a' occurs at most once. One obvious regex for this is (q|v)*(a(q|v)?). The analogous XSD model group is:

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

(I've changed from local element declarations to element references, to avoid having to declare query and validator twice each.)

In XSD 1.1, it should be possible to get the same effect with an all group:

<all>
  <element name="action" minOccurs="0" maxOccurs="1" />
  <element name="query" minOccurs="0" maxOccurs="unbounded" />
  <element name="validator" minOccurs="0" maxOccurs="unbounded" />
</all>
like image 102
C. M. Sperberg-McQueen Avatar answered Oct 21 '22 15:10

C. M. Sperberg-McQueen