I’m trying to create a schema for a <property> element which must have a <key> sub-element, and one of <val>, <shell> or <perl> and an optional <os> or <condition>, and the order of the sub-elements doesn’t matter.
Here are some sample for valid <property> elements:
<property>
<key>A</key>
<val>b</val>
</property>
<property>
<key>A</key>
<val>b</val>
<os>Windows</os>
</property>
<property>
<condition>a == 1</condition>
<key>A</key>
<perl>1+1</perl>
<os>unix</os>
</property>
Ideally, I thought of using <xs:all> for this:
<xs:element name="property">
<xs:complexType>
<xs:all>
<xs:element name="key" type="xs:string" />
<xs:choice>
<xs:element name="val" type="xs:string" />
<xs:element name="perl" type="xs:string" />
<xs:element name="shell" type="xs:string" />
</xs:choice>
<xs:element name="os" type="xs:string" minOccurs="0" />
<xs:element name="condition" type="xs:string" minOccurs="0" />
</xs:all>
</xs:complexType>
</xs:element>
But I found out that <xs:all> can contain only <xs:element> and not <xs:choice>. Can someone explain why is it?
More importantly, can someone provide a way to validate such a <property> element?
I can put the three elements – <val>, <perl> and <shell> – as optional elements in the <xs:all>, but I want the schema to validate that one and only one of the three exists in the element. Can this be done?
I think this is a bit better, as the “choice” is now it’s own element (typeFacet), but cannot be used directly as it is abstract.