I am trying to create an XSD, and trying to write the definition with the following requirement:
- Allow child element specified to appear any number of times (0 to unbounded)
- Allow child elements to be in any order
I looked around and found various solutions like this:
<xs:element name="foo">
<xsl:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="child1" type="xs:int"/>
<xs:element name="child2" type="xs:string"/>
</xs:choice>
</xs:complexType>
</xs:element>
But from what I understand xs:choice still only allows single element selection. Hence setting the MaxOccurs to unbounded like this should only mean that "any one" of the child elements can appear multiple times. Is this accurate?
If above solution is incorrect, how can I achieve what I stated above in my requirement?
EDIT: What if the requirement is as follows?
- Element child1 child2 can appear any
number of times (0 to unbounded) - Elements to be in any order
- Elements child3 and child4 should appear exactly once.
For example,
this xml is valid:
<foo>
<child1> value </child1>
<child1> value </child1>
<child3> value </child3>
<child2> value </child2>
<child4> value </child4>
<child1> value </child1>
</foo>
but this is not (missing child3)
<foo>
<child1> value </child1>
<child1> value </child1>
<child2> value </child2>
<child4> value </child4>
<child1> value </child1>
</foo>
Best Answer
The alternative formulation of the question added in a later edit seems still to be unanswered: how to specify that among the children of an element, there must be one named
child3
, one namedchild4
, and any number namedchild1
orchild2
, with no constraint on the order in which the children appear.This is a straightforwardly definable regular language, and the content model you need is isomorphic to a regular expression defining the set of strings in which the digits '3' and '4' each occur exactly once, and the digits '1' and '2' occur any number of times. If it's not obvious how to write this, it may help to think about what kind of finite state machine you would build to recognize such a language. It would have at least four distinct states:
No matter what state the automaton is in, '1' and '2' may be read; they do not change the machine's state. In the initial state, '3' or '4' will also be accepted; in the intermediate states, only '4' or '3' is accepted; in the final state, neither '3' nor '4' is accepted. The structure of the regular expression is easiest to understand if we first define a regex for the subset of our language in which only '3' and '4' occur:
To allow '1' or '2' to occur any number of times at a given location, we can insert
(1|2)*
(or[12]*
if our regex language accepts that notation). Inserting this expression at all available locations, we getTranslating this into a content model is straightforward. The basic structure is equivalent to the regex
(34)|(43)
:Inserting a zero-or-more choice of
child1
andchild2
is straightforward:If we want to minimize the bulk a bit, we can define a named group for the repeating choices of
child1
andchild2
:In XSD 1.1, some of the constraints on
all
-groups have been lifted, so it's possible to define this content model more concisely:But as can be seen from the examples given earlier, these changes to
all
-groups do not in fact change the expressive power of the language; they only make the definition of certain kinds of languages more succinct.