The purpose of the ID simple type in XSD is to define unique identifiers that are global to a document and emulate the ID attribute type available in the XML DTDs. The ID simple type provides a way to uniquely identify the containing element of the attribute defined using this data type through IDREF and IDREFS.
IDREF and IDREFS are simple types in XSD which can be used to refer to the values of the attributes with data type defined as ID and thus enabling links between documents. The difference between IDREF and IDREFS simple types is that IDREF simple type is a reference to the identifiers defined by the ID simple type whilst IDREFS is derived as a whitespace-separated list of what IDREF simple type can refer to.
The relationships between ID and IDREF / IDREFS simple types are synonymous with the primary key and foreign key relationship in the database. For every foreign key (IDREF / IDREFS), there must be a matching distinct and unique primary key (ID) which it is referring to.
For the identifiers defined in the ID, IDREF and IDREFS simple types to be valid:
- The value of an ID simple type must be unique and distinct within the XML document.
- For every identifier defined in IDREF and IDREFS simple types, the reference ID values must be in the XML document.
- The value of an ID, IDREF and IDREFS must be a named token and neither numerical identifiers nor whitespace is allowed (for example, the integer value 202 can not be an ID value).
XML Schema
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="orders">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="order" type="orderDetails" />
<xsd:element name="orderlist" type="orderLists" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="orderDetails">
<xsd:sequence>
<xsd:element name="customerName" type="xsd:string"/>
<xsd:element name="customerAddress" type="xsd:string"/>
<xsd:element name="customerContact" type="xsd:string"/>
<xsd:element name="orderIDREF" type="xsd:IDREF"/>
<xsd:element name="orderIDREFS" type="xsd:IDREFS"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="orderLists">
<xsd:sequence>
<xsd:element name="orderID" type="xsd:ID" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
XML Document
<?xml version="1.0" encoding="UTF-8"?>
<orders>
<order>
<customerName>Test</customerName>
<customerAddress>Test Address</customerAddress>
<customerContact>12345678</customerContact>
<orderIDREF>k1</orderIDREF>
<orderIDREFS>k1 k2</orderIDREFS>
</order>
<orderlist>
<orderID>k1</orderID>
<orderID>k2</orderID>
</orderlist>
</orders>
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="orders">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="order" type="orderDetails" />
<xsd:element name="orderlist" type="orderLists" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="orderDetails">
<xsd:sequence>
<xsd:element name="customerName" type="xsd:string"/>
<xsd:element name="customerAddress" type="xsd:string"/>
<xsd:element name="customerContact" type="xsd:string"/>
<xsd:element name="orderIDREF" type="xsd:IDREF"/>
<xsd:element name="orderIDREFS" type="xsd:IDREFS"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="orderLists">
<xsd:sequence>
<xsd:element name="orderID" type="xsd:ID" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
XML Document
<?xml version="1.0" encoding="UTF-8"?>
<orders>
<order>
<customerName>Test</customerName>
<customerAddress>Test Address</customerAddress>
<customerContact>12345678</customerContact>
<orderIDREF>k1</orderIDREF>
<orderIDREFS>k1 k2</orderIDREFS>
</order>
<orderlist>
<orderID>k1</orderID>
<orderID>k2</orderID>
</orderlist>
</orders>
The W3C XML Schema contains many flexible XPath-based features for describing uniqueness constraint. One of these features is declared with the xs:unique element. The xs:unique element defines that an element or an attribute value must be unique within the scope.
The xs:unique element must contain the followings (in order):
- one and only one selector element which contains an XPath expression that specifies the set of elements across which the values specified by the field must be unique
- one or more field elements which contains an XPath expression that specifies the values that must be unique for the set of elements specified by the selector element. If there is a set of field elements, the values for a single field element may or may not be unique across the selected elements but the combination of all the fields must be unique
XML Schema
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="products">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="product" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="id" type="xsd:integer" />
<xsd:element name="name" type="xsd:string" />
<xsd:element name="price" type="xsd:decimal" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:unique name="prodIDUnique">
<xsd:selector xpath="./product"/>
<xsd:field xpath="id"/>
</xsd:unique>
</xsd:element>
</xsd:schema>
XML Document
<?xml version="1.0" encoding="UTF-8"?>
<products>
<product>
<id>546</id>
<name>Nike Soccer Ball</name>
<price>120</price>
</product>
<product>
<id>547</id>
<name>Adidas Sports Shoes</name>
<price>600</price>
</product>
</products>
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="products">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="product" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="id" type="xsd:integer" />
<xsd:element name="name" type="xsd:string" />
<xsd:element name="price" type="xsd:decimal" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:unique name="prodIDUnique">
<xsd:selector xpath="./product"/>
<xsd:field xpath="id"/>
</xsd:unique>
</xsd:element>
</xsd:schema>
XML Document
<?xml version="1.0" encoding="UTF-8"?>
<products>
<product>
<id>546</id>
<name>Nike Soccer Ball</name>
<price>120</price>
</product>
<product>
<id>547</id>
<name>Adidas Sports Shoes</name>
<price>600</price>
</product>
</products>
References
- W3C Recommendation XML Schema Part 2: Datatypes Second Edition
Paul V. Biron and Ashok Malhotra Editors 2004
http://www.w3.org/TR/xmlschema-2 - w3schools.com
http://www.w3schools.com/schema/el_unique.asp - RELAX NG By Eric van der Vlist
Publisher: O'Reilly Media
Released: December 2003
ISBN: 978-0-596-00421-7
ISBN 10: 0-596-00421-4
5 Comments:
Excellent article. I am an IT Consultant of 20+ years and have read many articles covering this aspect of XSD. Very few articles express this facility as well and as succinctly as this.
May 12, 2012 at 10:09 PM
Hi this is really a nice piece of work.
I was having 1 query related to XML please help me out.
I have one xsd file with 2 elements "X" and "Y".
Is there anyway to change "Y" value automatically when "X" value is changed.
May 26, 2012 at 10:43 PM
Good post. One thing to mention about ID values: they must be xml names as you said, which means they must START with a character. After that, they can be a numeric identifier.
I consider it a best practice to use the referenced element name as the initial character followed by a sequence number.
October 31, 2012 at 11:56 PM
thanks a lot for the simple explanation!
January 7, 2014 at 12:02 AM
You saved my day. Thanks a lot
June 13, 2016 at 9:33 PM
Post a Comment