Reputation: 98
I have a rather unusual problem it seems. I have an xml that looks roughly something liket his:
<?xml version="1.0" encoding="utf-8"?>
<root xmlns="tbd">
<A>
<B id="01">
<C id="02" />
<C id="03" />
</B>
<B id="04">
<C id="05" />
</B>
</A>
<A>
<B id="01">
<C id="02" />
<C id="03" />
</B>
<B id="04">
<C id="05" />
</B>
</A>
</root>
As you can see, the block A can repeat n times. My problem is validating that the id attribute is unique for all decendents of A (child, grandchild, asf.). So far I managed to validate that the id of B is unique inside of A, and that the id of C is unique inside of B with am XSD that looks something like this:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="tbd" xmlns:tbd="tbd" elementFormDefault="qualified">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="A" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="B" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="C" maxOccurs="unbounded">
<xs:ComplexType>
<xs:attribute name="id" type="xs:int" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:attribute name="id" type="xs:int" use="required" />
<xs:unique name="UniqueC">
<xs:selector xpath="tbd:C" />
<xs:field xpath="@id" />
</xs:unique>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:unique name="UniqueB">
<xs:selector xpath="tbd:B" />
<xs:field xpath="@id" />
</xs:unique>
</xs:element>
</xs:sequence>
</xs:compleyType>
</xs:element>
</xs:schema>
What I'm looking for is a validation like type="xs:ID" but not for the whole document but only inside of A so that the following example would be invalid (right now this would be valid):
<?xml version="1.0" encoding="utf-8"?>
<root xmlns="tbd">
<A>
<B id="01">
<C id="01" /> <!-- should be invalid -->
<C id="02" />
<C id="04" />
</B>
<B id="04"> <!-- should be invalid -->
<C id="02" /> <!-- should be invalid -->
<C id="05" />
</B>
</A>
<A>
<B id="01">
<C id="012" />
<C id="02" />
<C id="04" />
</B>
<B id="042">
<C id="05" />
</B>
</A>
</root>
Upvotes: 2
Views: 505
Reputation: 6016
xs:selector
is used to select a list of nodes accross which the field value should be unique. So, if you want id to be unique across every B and every C then you need to select all that nodes in the selector. Example (note that in XPath the |
character means union of nodes):
<xs:selector xpath="tbd:B | tbd:B/tbd:C" />
Upvotes: 1