2
votes

I am trying to create an XSD, which allows child elements to be in any order. But each child element has its own minOccurs and maxOccurs.

My XSD:

<xsd:complexType name="Samples">
<xsd:sequence > 
  <xsd:element name="Sample1" minOccurs="1" maxOccurs="1">
    <xsd:complexType>
      <xsd:simpleContent>
        <xsd:extension base="xsd:boolean" />
      </xsd:simpleContent>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="Sample2" minOccurs="0" maxOccurs="unbounded">
    <xsd:complexType>
      <xsd:simpleContent>
        <xsd:extension base="xsd:string" />
      </xsd:simpleContent>
    </xsd:complexType>
  </xsd:element>
</xsd:sequence>

For Example a valid XML:

<Samples>
<Sample2></Sample2>
<Sample1></Sample1>
<Sample2></Sample2>
</Samples>

For Example a not valid XML (Sample1 can be choose only one time):

<Samples>
<Sample2></Sample2>
<Sample1></Sample1>
<Sample2></Sample2>
<Sample1></Sample1>
</Samples>

But i don't know, how i can mix the order, while all elements have its own constraint.

Thanks for help

2

2 Answers

2
votes

What if you try this:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="Samples">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="Sample2" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element name="Sample1" minOccurs="1" maxOccurs="1"/>  
        <xsd:element name="Sample2" minOccurs="0" maxOccurs="unbounded"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

Of course, you should add your restrictions to each element:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:complexType name="Sample1Type">
      <xsd:simpleContent>
        <xsd:extension base="xsd:boolean" />
      </xsd:simpleContent>
   </xsd:complexType>
   <xsd:complexType name="Sample2Type">
      <xsd:simpleContent>
        <xsd:extension base="xsd:string" />
      </xsd:simpleContent>
   </xsd:complexType>
  <xsd:element name="Samples">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element type="Sample2Type" name="Sample2" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element type="Sample1Type" name="Sample1" minOccurs="1" maxOccurs="1"/>  
        <xsd:element type="Sample2Type" name="Sample2" minOccurs="0" maxOccurs="unbounded"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

OR even shorter for simple types:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="Samples">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element type="xsd:string" name="Sample2" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element type="xsd:boolean" name="Sample1" minOccurs="1" maxOccurs="1"/>  
        <xsd:element type="xsd:string" name="Sample2" minOccurs="0" maxOccurs="unbounded"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

P.S.::

There are unfortunately no XSD elements like xsd:sequence, which will allow, what you ask.

0
votes

What you want looks like xsd:all; however, since xsd:all only works for elements for which maxOccurs is 1, it will not work here. If you can combine choices and sequences to constrain your content, one way to go around duplication of definition (avoid defining twice) is to define Sample1 and Sample 2 as global elements and then ref them under your compositors. If defining global elements is not an option except for your root elements, then you could at least define the types globally - this way you maximize the reuse, and somewhat getting closer to your requirement "without defining twice"...