5
votes

I am stuck with XSD's 'choice' element description. It states, that only one element, from those found inside that tag can be found in valid XML:

Allows one and only one of the elements contained in the selected group to be present within the containing element.

(http://msdn.microsoft.com/en-us/library/ms256109%28v=vs.110%29.aspx)

From the other hand, looks like attribute maxOccurs="unbounded" may change the situation to the opposite, and now any number of elements may appear inside the type desribed with 'choice': please refer to this question:

XSD - how to allow elements in any order any number of times?

So how many elements can be found inside the type which has a choice indicator inside?

2

2 Answers

7
votes

The MSDN page that says choice allows "one and only one of the elements contained in the selected group" is badly phrased. Well, no, that's too generous. As a description of xsd:choice, it's flat wrong.

A choice contains zero or more alternatives, and matches part of the input if and only if at least one of those alternatives matches the input. (In practice, this almost always means 'if exactly one of those alternatives matches the input': if more than one alternative matches the input, the content model almost certainly violates the 'Unique Particle Attribution' rule.)

So a choice among alternatives A1, A2, A3, ... An matches a sequence of elements in the input if and only if A1 matches that sequence, or A2, or A3, ..., or An.

If each alternative A1, ..., An is a single element with minOccurs = maxOccurs = 1, so none of them are repeatable, and if the choice itself is not repeatable, then the description you quote is more or less accurate. But any of several things can result in multiple elements being matched by a single choice:

  • The choice may itself be repeatable (as already pointed out by lexicore); the following choice matches any sequence of A, B, and C elements:

    <xsd:choice minOccurs="0" maxOccurs="unbounded">
      <xsd:element ref="A"/>
      <xsd:element ref="B"/>
      <xsd:element ref="C"/>
    </xsd:choice>
    
  • The individual alternatives may be repeatable; the following choice matches any non-empty sequence of A elements, or any non-empty sequence of B elements, or exactly one C element:

    <xsd:choice>
      <xsd:element ref="A" maxOccurs="unbounded"/>
      <xsd:element ref="B" maxOccurs="unbounded"/>
      <xsd:element ref="C"/>
    </xsd:choice>
    
  • The individual alternatives may be sequences or choices that match more than one element; the following choice matches any non-empty sequence of A and B elements, or the sequence D, E, F:

    <xsd:choice>
      <xsd:choice maxOccurs="unbounded">
        <xsd:element ref="A"/>
        <xsd:element ref="B"/>
      </xsd:choice>
      <xsd:sequence>
         <xsd:element ref="D"/>
         <xsd:element ref="E"/>
         <xsd:element ref="F"/>
      </xsd:sequence>
    </xsd:choice>
    

The answer to your question

So how many elements can be found inside the type which has a choice indicator inside?

is the same as the answer to the question

So how many elements can be found inside an element?

or

So how long is a sequence of symbols which matches a regular expression?

5
votes

So how many elements can be found inside the type which has a choice indicator inside?

Depends on minOccurs/maxOccurs of the choice element.

Exactly one of child1 or child2:

<xs:choice>
  <xs:element name="child1" type="xs:int"/>
  <xs:element name="child2" type="xs:string"/>
</xs:choice>

One of child1 or child2 or none:

<xs:choice minOccurs="0">
  <xs:element name="child1" type="xs:int"/>
  <xs:element name="child2" type="xs:string"/>
</xs:choice>

At least one or more of child1 or child2, in arbitrary order:

<xs:choice maxOccurs="unbounded">
  <xs:element name="child1" type="xs:int"/>
  <xs:element name="child2" type="xs:string"/>
</xs:choice>

Zero or more of child1 or child2, in arbitrary order:

<xs:choice minOccurs="0" maxOccurs="unbounded">
  <xs:element name="child1" type="xs:int"/>
  <xs:element name="child2" type="xs:string"/>
</xs:choice>

I personally try to avoid repeatable choices and sequences in schemas as they make structures too "heterogeneous".