views:

335

answers:

3

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>
+2  A: 

In the schema you have in your question, child1 or child2 can appear in any order, any number of times. So this sounds like what you are looking for.

Edit: if you wanted only one of them to appear an unlimited number of times, the unbounded would have to go on the elements instead:

<xs:element name="foo">
   <xsl:complexType>
     <xs:choice>
       <xs:element name="child1" type="xs:int" maxoccurs="unbounded"/>
       <xs:element name="child2" type="xs:string" maxoccurs="unbounded"/>
     </xs:choice>
   </xs:complexType>
</xs:element>
xcut
basically yes, i am looking for elements child1, child2 to appear in any order, any number of times.. the answer you provided here only works for single element, right? or does this solve my requirement also?
jvtech
The schema in your question meets your requirement; the alternative schema in my answer is for a single element. Hope that clears it up! :)
xcut
@Pavel, @xcut, Thanks for clarification, see edited requirement.. any thoughts?
jvtech
jvtech: you cannot satisfy that edited requirement with XML schema; the only way to achieve it would be if child3 and child4 can appear only at the end. In which case you need a sequence containing a choice and then the two elements.
xcut
A: 

You should find that the following schema allows the what you have proposed.

  <xs:element name="foo">
    <xs:complexType>
      <xs:sequence minOccurs="0" maxOccurs="unbounded">
        <xs:choice>
          <xs:element maxOccurs="unbounded" name="child1" type="xs:unsignedByte" />
          <xs:element maxOccurs="unbounded" name="child2" type="xs:string" />
        </xs:choice>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

This will allow you to create a file such as:

<?xml version="1.0" encoding="utf-8" ?>
<foo>
  <child1>2</child1>
  <child1>3</child1>
  <child2>test</child2>
  <child2>another-test</child2>
</foo>

Which seems to match your question.

Steven_W
`minOccurs` and `maxOccurs` are restricted to 1 for children of `xs:all`.
Pavel Minaev
Pavel: Thanks ... I found this out after double-checking my post and then edited it to remove the xs:all
Steven_W
+1  A: 

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?

No. The choice happens individually for every "repetition" of xs:choice that occurs due to maxOccurs="unbounded". Therefore, the code that you have posted is correct, and will actually do what you want as written.

Pavel Minaev