Reputation: 505
I have an XML Schema that defines a complexType as follows:
<xs:complexType name="CompType">
<xs:sequence>
<xs:element name="A" type="TypeA" minOccurs="0" maxOccurs="1"/>
<xs:choice minOccurs="1" maxOccurs="12">
<xs:element name="B" type="TypeB"/>
<xs:element name="C" type="TypeC"/>
<xs:element name="D" type="TypeD"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
I need it to validate an XML element which can have a max of 12 "normal" sub-elements (normal = TypeB, TypeC or TypeD), but may have an additional "special" sub-element of TypeA.
As it is it works, but I do not want to restrict the "special" sub-element to be always the first. In other words, I want to be able to do something like the below, with an added restriction that there can only be a single TypeA sub-element, and no more than 12 "normal" sub-elements.
<xs:complexType name="CompType">
<xs:sequence>
<xs:choice minOccurs="1" maxOccurs="13">
<xs:element name="A" type="TypeA"/>
<xs:element name="B" type="TypeB"/>
<xs:element name="C" type="TypeC"/>
<xs:element name="D" type="TypeD"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
Is this at all possible? If yes, can someone indicate how or, at least, point me in the right direction?
Upvotes: 1
Views: 2764
Reputation: 111726
The Unique Particle Attribution (UPA) constraint will thwart any clever attempts at achieving this goal for XSD 1.0.
Even the case where you want 0 or more B, C, or D's and only 0 or 1 A's in arbitrary order cannot be done. Consider:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="1.0">
<xs:element name="X" type="CompType"/>
<xs:complexType name="CompType">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="B"/>
<xs:element name="C"/>
<xs:element name="D"/>
</xs:choice>
<xs:element name="A" minOccurs="0"/>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="B"/>
<xs:element name="C"/>
<xs:element name="D"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:schema>
Validation would require look ahead of more than one tag and thus would violate the UPA. Xerces would express its unhappiness:
cos-nonambig: B and B (or elements from their substitution group) violate "Unique Particle Attribution". During validation against this schema, ambiguity would be created for those two particles.
The problem remains in the maxOccurs=12 scenario unless you want to get crazy and enumerate all possibilities.
If you can use XSD 1.1, you may be able to use its xs:assert
facilities. (Untested:)
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="1.1">
<xs:element name="X" type="CompType"/>
<xs:complexType name="CompType">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="A"/>
<xs:element name="B"/>
<xs:element name="C"/>
<xs:element name="D"/>
</xs:choice>
<xs:assert test="(count(./A) le 1) and (count(./A) + count(./B) + count(./C) + count(./D) le 13)"/>
</xs:complexType>
</xs:schema>
Upvotes: 1