XML Schema – xs:key and xs:keyref

xs:key and xs:keyref in XML models the relationship between primary key and foreign key in a database.  xs:key ensures that the pieces of data in an XML document are unique and not null .  They enforce data integrity in the XML Document.

xskey

xs:unique and xs:ID

The xs:unique element and the xs:ID datatype ensure that the pieces of data in an XML document are unique

xsid

XML Schema Exercise:

1. Create a Cart element. Each Cart element must have multiple instances of child Category element

2. Category element can have multiple instances of child Book and Sales element n

3. Each Book element must have a BookNumber attribute whose value is unique within Category.

4. Each Sales must have an ID attribute whose value matches one of these unique BookNumbers

xs:selector and xs:field

The identity constraint “keyBookNumber” does not allow the incoming xml files to have duplicate values for book number. It is defined using xs:key.

xs:selector: The context in which the primary key constraint should be applied. In this case, the primary key is applied on the Book element. Hence the xs:selector is Book

xs:field: The field that uniquely identifies the record. The field that uniquely identifies the Book record in our case is Number.

<xs:key name="keyBookNumber">
	<xs:selector xpath="Book"/>
	<xs:field xpath="@BookNumber"/>
</xs:key>

The below XML Schema diagram was drawn using Altova XMLSpy. Here Catalog is the root element. It has multiple Book elements which can be uniquely identified using the BookNumber attribute. All attributes have a prefix @.

 

xsselector

After applying the primary key constraint xs:key the XML Schema Document will look like this:

Schemaexercise1

Now lets see the relationship between the book and sales records. As per the exercise  ” each Sales must have an ID attribute whose value matches one of these unique BookNumbers”

relationship

Define xs:keyref constraint “referBookNumber” with selector as Sales and field as @ID. Specify refer as keyBookNumber.
This ensures that each Sales must have an ID attribute whose value matches one of these unique BookNumbers.

output

So the solution for this exercise is as below:

<?xml version="1.0" encoding="UTF-8"?>
<!-- edited with XMLSpy v2009 (http://www.altova.com) by Aruna (Nil) -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
	<xs:element name="Cart">
		<xs:annotation>
			<xs:documentation>Comment describing your root element</xs:documentation>
		</xs:annotation>
		<xs:complexType>
			<xs:sequence>
				<xs:element name="Category" maxOccurs="unbounded">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="Book" maxOccurs="unbounded">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="Title" type="xs:string"/>
										<xs:element name="Author" type="xs:string"/>
										<xs:element name="Description" type="xs:string"/>
										<xs:element name="Price" type="xs:double"/>
										<xs:element name="Quantity" type="xs:integer"/>
										<xs:element name="ISBN" type="xs:integer"/>
									</xs:sequence>
									<xs:attribute name="BookNumber" type="xs:integer"/>
								</xs:complexType>
							</xs:element>
							<xs:element name="Sales" maxOccurs="unbounded">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="Customer" type="xs:string"/>
										<xs:element name="Region" type="xs:string"/>
										<xs:element name="TransactionStatus" type="xs:string"/>
									</xs:sequence>
									<xs:attribute name="ID" type="xs:integer"/>
								</xs:complexType>
							</xs:element>
						</xs:sequence>
					</xs:complexType>
					<xs:key name="keyBookNumber">
						<xs:selector xpath="Book"/>
						<xs:field xpath="@BookNumber"/>
					</xs:key>
					<xs:keyref name="referBookNumber" refer="keyBookNumber">
						<xs:selector xpath="Sales"/>
						<xs:field xpath="@ID"/>
					</xs:keyref>
				</xs:element>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
</xs:schema>