2010-11-05

What are ID, IDREF, and IDREFS simple types in XSD? How is xs:unique used to constrain values? Give examples to explain the usage of these XSD constructs.




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).
The following example illustrates the ID, IDREF and IDREFS approach. Notice that the element “orderID” is defined as ID simple type in XSD and it is represented by two values, “k1” and “k2”, in the example XML document. In the XML document, the value for the element “orderIDREF” must match the value of any elements “orderID” (in this case “k1” or “k2”) in order for the document to be valid. For the element “orderIDREFS”, its value can be made up of a list of the “orderID” element values separated by whitespace or a single value which match the value of any elements “orderID” just like the case for the element “orderIDREF”.

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>

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
The following example illustrates the uniqueness constraint using xs:unique element. Each product element must have an id child element whose value is unique within products. If any product id is duplicated within the document, the document will be checked as invalid under the uniqueness constraint by the XML Schema.

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>


References

5 Comments:

Tracy-Gregory said...

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.

kunal said...

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.

DaveH said...

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.

yioann said...

thanks a lot for the simple explanation!

Chamara D. Jayaweera said...

You saved my day. Thanks a lot

Post a Comment