Search code examples
xmlxsdxsd-validationcomplextype

XSD 2 elements once, 1 element 1+ any order


I am working on an XML Schema that includes 3 elements which can be in any order.

  • Two of them have to appear exactly once,
  • The third element can appear once or more than once.
  • All three are required.

In the example below, every bio has ONE favoriteColor and ONE favoriteNumber, and AT LEAST ONE comment. I would LIKE them to be allowed in any order, (including alternating).

<xs:element name="bio">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="favoriteColor" maxOccurs="1" minOccurs="1"/>
            <xs:element name="favoriteNumber" maxOccurs="1" minOccurs="1"/>
            <xs:element name="comment" maxOccurs="unbounded" minOccurs="1"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

Once possible option is <xs:choice>, but it allows only ONE of the options. It seems unwieldy to list every possible order combination as an alternate sequence: (abc, acb, bac, bca, cab, cba)... and it still doesn't account for the possibility of having comments interspersed between the other two. (e.g. "comment, number, comment, color, comment, comment" should be allowed)

<xs:all> would work well, except it only allows a maximum of 1 instance of each. I need to allow multiple "comment"s. I could put <xs:element name="comment" maxOccurs="unbounded" minOccurs="0"/> both above and below an "all" tag, but that doesn't work. See below:

<xs:element name="bio">
    <xs:complexType>
        <xs:sequence>
            <xs:element ref="comment" maxOccurs="unbounded" minOccurs="0"/>
            <xs:all> <!-- not allowed here -->
                <xs:element ref="favoriteColor" maxOccurs="1" minOccurs="1"/>
                <xs:element ref="favoriteNumber" maxOccurs="1" minOccurs="1"/>
                <xs:element ref="comment" maxOccurs="1" minOccurs="1"/>
            </xs:all>
            <xs:element ref="comment" maxOccurs="unbounded" minOccurs="0"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

Any suggestions? There are quite a few questions on this board that pertain to the order of elements in a schema, but I couldn't find any that addressed what I am trying to do (where I have a combination of "only once" and "at least once)."


Solution

  • I don't think possible. Even

    <xs:sequence>
         <xs:element ref="comment" maxOccurs="unbounded" minOccurs="0" /> 
         <xs:element ref="comment" maxOccurs="unbounded" minOccurs="0" />
    </xs:sequence> 
    

    will give you error. (cos-nonambig: "test":comment and "test":comment (or elements from their substitution group) violate "Unique Particle Attribution". During validation against this schema, ambiguity would be created for those two particles.)