If I have the following element spec in XSD I can add the <xs:unique>
constraint as a child of <xs:element name="Parent">
but I can't get it to work as a child of <xs:element name="Child">
:
<xs:element name="Parent">
<xs:complexType>
<xs:element name="Child" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="Key" type="xs:string" use="required" />
</xs:complexType>
<!-- Option A: insert unique constraint here with selector . -->
</xs:element>
</xs:complexType>
<!-- Option B: insert unique constraint here with selector ./Child -->
</xs:element>
This is the unique constraint that works as a child of <xs:element name="Parent">
:
<xs:unique name="ChildKey">
<xs:selector xpath="./Child"/>
<xs:field xpath="@Key" />
</xs:unique>
But this unique constraint doesn't work as a child of <xs:element name="Child">
:
<xs:unique name="ChildKey">
<xs:selector xpath="."/>
<xs:field xpath="@Key" />
</xs:unique>
Do I need to change the selector XPath in the second case?
If you think about it, the selector "." will always return the current node; the selector gives you a node set with one node only... So, within a set with one node only, the uniqueness is guaranteed, since an attribute with a given name can only happen once. This should explain why you cannot get it the way you think it should work.
When you set it at the parent level, it works because you are now enforcing uniqueness among a set of Child nodes.
In database terms, a constraint such as what you need can only be defined at the table level. This is what it would look like (I've rewritten the XSD slightly to get a good E/R out of it).
XSD:
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns:tns="http://tempuri.org/XMLSchema.xsd" xmlns="http://tempuri.org/XMLSchema.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Parent" type="Parent">
<xs:unique name="ParentKey">
<xs:selector xpath="tns:Child"/>
<xs:field xpath="@Key"/>
</xs:unique>
</xs:element>
<xs:complexType name="Parent">
<xs:sequence>
<xs:element name="Child" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="Key" type="xs:string" use="required"/>
</xs:complexType>
<xs:unique name="ChildKey">
<xs:selector xpath="."/>
<xs:field xpath="@Key"/>
</xs:unique>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
XSD Diagram:
The equivalent ADO.NET E/R:
An XML showing errors:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<Parent xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/XMLSchema.xsd">
<Child Key="Key1"/>
<Child Key="Key1"/>
</Parent>
Error message:
Error occurred while loading [], line 5 position 3
There is a duplicate key sequence 'Key1' for the 'http://tempuri.org/XMLSchema.xsd:ParentKey' key or unique identity constraint.
Unique.xml is invalid.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With