4

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!

Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
ogee
  • 917
  • 1
  • 6
  • 11

4 Answers4

5

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>
Alohci
  • 78,296
  • 16
  • 112
  • 156
  • Hello Alohci - i am curious to why my solution doesn't work. Could you please share your concerns about that? – Mo. Jan 04 '09 at 12:17
2

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"

Mo.
  • 15,033
  • 14
  • 47
  • 57
0

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

Yuval Adam
  • 161,610
  • 92
  • 305
  • 395
  • Thanks for your answer, however I think it more complex then this. I have the error of: cos-nonambig: x and x (or elements from their substitution group) violate "Unique Particle Attribution". (note that your suggestion is all under "xsd:sequence") Do you have other idea instead? Thanks! – ogee Jan 04 '09 at 09:38
  • Elements in XSD are not optional by default. Default is minOccurs="1". Added minOccurs="0" to each gives the problem that Oger states in his comment. – Alohci Jan 04 '09 at 12:30
0

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>  
davidsheldon
  • 38,365
  • 4
  • 27
  • 28
  • This does not allow the group to be a single "y" element, but does allow y-x-y-x as valid sequence which shouldn't be allowed. – Alohci Jan 04 '09 at 12:34