Reputation: 5735
Say that I have a PetCage
element that should contains one and only one AnimalElement
type like so:
<PetCage>
<Cat Name="Kitty">
</PetCage>
<PetCage>
<Dog Name="Buddy">
</PetCage>
Both Cat
and Dog
are of AnimanlElement
type. How can I express said rule in XSD?
Upvotes: 1
Views: 8488
Reputation: 12019
What you require is a choice element in your schema. It'll allow you to express that only one from a set of elements may appear.
EDIT: you'll need to specify a name for the element, either directly via name
or in reference to an element defined elsewhere via ref
.
Your only alternative as far as I know is to have something like this:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="PetCage">
<xs:complexType>
<xs:sequence>
<xs:element name="animal" type="Animal" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="Animal" abstract="true">
<xs:attribute name="Name" type="xs:string" />
</xs:complexType>
<xs:complexType name="Cat">
<xs:complexContent>
<xs:extension base="Animal"></xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
This would validate XML files of a form like this:
<?xml version="1.0" encoding="UTF-8"?>
<PetCage>
<animal xsi:type="Cat" Name="String"/>
</PetCage>
Unfortunately this leaves you tied to that animal
element name. I doubt that XML Schema allows you to specify a specific type and lets you use a wildcard for the name. XML Schema validates based on element names and, if the element is defined with an abstract type, the xsi:type
attribute. There is an xs:any
declaration, but that can't be tied to any specific type. The following will validate as best as possible, but still allows any element defined under the schema root to be used:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="PetCage">
<xs:complexType>
<xs:sequence>
<xs:any processContents="strict" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="Animal" abstract="true">
<xs:attribute name="Name" type="xs:string" />
</xs:complexType>
<xs:element name="cat" />
<xs:complexType name="Cat">
<xs:complexContent>
<xs:extension base="Animal"></xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
It would validate this correctly:
<?xml version="1.0" encoding="UTF-8"?>
<PetCage>
<cat Name="snookums"/>
</PetCage>
... but it wouldn't stop you from putting a PetCage in a PetCage.
I'm hoping someone with good knowledge of the XML Schema spec can confirm that this is correct or, preferably, offer the desired solution.
Upvotes: 3
Reputation: 31780
<xs:complexType name="PetCage">
<xs:choice>
<xs:element name="Cat" type="AnimanlElement" />
<xs:element name="Dog" type="AnimanlElement" />
</xs:choice>
</xs:complexType>
<!-- AnimanlElement definition -->
<xs:complexType name="AnimanlElement">
<xs:attribute name="Name" type="xs:string" />
</xs:complexType>
For more: http://www.w3schools.com/Schema/el_choice.asp
Upvotes: 2