Reputation: 44
I'm fairly new to XSD validation so there might be something crucial that I am missing, but I've looked around quite a bit and can't seem to find an appropriate solution.
What I'm trying to do is something like this:
Consider this XML example, I'm forced to use (simplified)
.
.
.
<categories>
<orange id="1" value="10">...</orange>
<orange id="2" value="10">...</orange>
<brown id="1" value="10">...</brown>
<brown id="2" value="10">...</brown>
<brown id="3" value="10">...</brown>
.
.
.
</categories>
Basically I want to ensure that the id is unique for all orange categories and brown categories but not unique overall.
My initial XSD would look something like this:
.
.
.
<xs:element name="categories">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element name="orange">
<xs:complexType>
<xs:attribute name="id" type="xs:integer" use="required"/>
<xs:attribute name="value" type="xs:integer" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="brown ">
<xs:complexType>
<xs:attribute name="id" type="xs:integer" use="required"/>
<xs:attribute name="value" type="xs:integer" use="required"/>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
<xs:key name="catKeys">
<xs:selector xpath="/*" />
<xs:field xpath="@id" />
</xs:key>
</xs:element>
Above XSD checks the id-uniqueness across all categories -> The XML won't validate.
Upvotes: 2
Views: 204
Reputation: 111726
You're very close. Simply use two xs:key
elements, one for each of orange
and brown
:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="categories">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element name="orange">
<xs:complexType>
<xs:attribute name="id" type="xs:integer" use="required"/>
<xs:attribute name="value" type="xs:integer" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="brown ">
<xs:complexType>
<xs:attribute name="id" type="xs:integer" use="required"/>
<xs:attribute name="value" type="xs:integer" use="required"/>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
<xs:key name="orangeKeys">
<xs:selector xpath="orange"/>
<xs:field xpath="@id"/>
</xs:key>
<xs:key name="brownKeys">
<xs:selector xpath="brown"/>
<xs:field xpath="@id"/>
</xs:key>
</xs:element>
</xs:schema>
Then your XML will be valid, given that it has unique id
elements with scopes separate for orange
vs brown
elements.
Upvotes: 2