Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unordered elements in XSD with obligatory and unbounded elements?

Tags:

I have the following element in my XSD:

<xs:element name="documents" minOccurs="1" maxOccurs="1">
    <xs:complexType>
        <xs:sequence>

            <xs:element name="invoice" minOccurs="1" maxOccurs="1">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:minLength value="1"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>

            <xs:element name="report" minOccurs="0" maxOccurs="1">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:minLength value="1"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>

            <xs:element name="additional" minOccurs="0" maxOccurs="unbounded">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:minLength value="1"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>

        </xs:sequence>
    </xs:complexType>
</xs:element>

You can see that documents must always have an invoice and optionally it can have a single report and zero or more additionals.

The problem is that these elements can have a different order of appearance, so I can´t use a sequence anymore. I tried to use all but then the problem is the additional element, since it has maxOccurs="unbounded".

How can I have an unordered list of elements with one of those those elements being always required and another element having unlimited occurrences?

like image 754
ivan0590 Avatar asked Jun 22 '16 13:06

ivan0590


1 Answers

Three suggestions. Either:

  1. Impose an ordering. Almost always the perceived need to allow any ordering of elements is unnecessary in practice.
  2. Use XSD 1.1, where maxOccurs="unbounded" is supported on xsd:all.
  3. Use a wrapper around the element you wish to allow to have maxOccurs="unbounded". See additionalList in the XSD below for a working example.

XSD with wrapper element to work around unbounded xsd:all limitation

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
           elementFormDefault="qualified">
  <xs:element name="documents">
    <xs:complexType>
      <xs:all>
        <xs:element name="invoice" minOccurs="1" maxOccurs="1">
          <xs:simpleType>
            <xs:restriction base="xs:string">
              <xs:minLength value="1"/>
            </xs:restriction>
          </xs:simpleType>
        </xs:element>
        <xs:element name="report" minOccurs="0" maxOccurs="1">
          <xs:simpleType>
            <xs:restriction base="xs:string">
              <xs:minLength value="1"/>
            </xs:restriction>
          </xs:simpleType>
        </xs:element>
        <xs:element name="additionalList" minOccurs="0">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="additional" minOccurs="0" maxOccurs="unbounded">
                <xs:simpleType>
                  <xs:restriction base="xs:string">
                    <xs:minLength value="1"/>
                  </xs:restriction>
                </xs:simpleType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:all>
    </xs:complexType>
  </xs:element>
</xs:schema>
like image 188
kjhughes Avatar answered Oct 11 '22 16:10

kjhughes