Question

I need your help to define a special case in XML schema: A sequence that contains two elements: 'x' and 'y' whereas:

  • <x> element can appear 0 to unbound times in the sequence

  • <y> element can appear 0 to 1 time in the sequence

  • <x> and <y> locations can be anywhere - that is, it is possible to have unbound times the <x> element and then a single <y> element, and then unbound times the <x> element.

XML examples of this problem:

Example #1

<x>stuff</x>
<y>stuff</y>
<x>stuff</x>

Example #2

<y>stuff</y>
<x>stuff</x>
<x>stuff</x>

Example #3

<x>stuff</x> 
<x>stuff</x>
<y>stuff</y>
<x>stuff</x>

Thanks!

Was it helpful?

Solution

For various reasons, none of Yuval's, Mo's or davidsheldon's samples work. Here's one that does.

    <xs:complexType name="myComplexType">
    <xs:sequence>
        <xs:element name="x" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
        <xs:sequence minOccurs="0">
            <xs:element name="y" type="xs:string"/>
            <xs:element name="x" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:sequence>
    </xs:complexType>

OTHER TIPS

EDIT: As Alohci mentioned, my solution is incorrect. According to the spec, an element in xs:all can only appear zero or one time. Sorry for any inconvenience

I think what you want isn't a sequence. A sequence defines not only the elements but also the order. And in your case the order may change. Have you tried xs:all?

<xs:complexType name="myComplexType">
  <xs:all>
    <xs:element name="x" type="xs:string" maxOccurs="unbounded"/>
    <xs:element name="y" type="xs:string" maxOccurs="1"/>
  </xs:all>
</xs:complexType>

Another appraoch might be to make it a sequence but mark the sequence to be maxOccurs="unbounded"

It has been a while since I used schema, but I think sequences are your answer here.

You need to have an unbounded number of choices between (an x), or (a y followed by an x).

<xsd:element name="parent">
  <xsd:complexType>
    <xsd:choice maxOccurs="unbounded">
      <xsd:element name="x" type="xs:string"/>
      <xsd:sequence>
        <xsd:element name="y" type="xsd:string" />
        <xsd:element name="x" type="xsd:string" />
      </xsd:sequence>
    </xsd:choice>
  </xsd:complexType>  
</xsd:element>  

Not too complicated. Off the top of my head, it should be something like this:

<xs:element name="x" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="y" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="x" type="xs:string" minOccurs="0" maxOccurs="unbounded"/> 

Since each element in XSD is optional by default, this XSD will match the XML structure you have defined, with the y element appearing anywhere before, after or between the x elements, with a maximum occurence of 1

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top