facebook google plus twitter
Webucator's Free XML Schema Tutorial

Lesson: XML Schema Keys

Welcome to our free XML Schema tutorial. This tutorial is based on Webucator's Introduction to XML Schema course.

Lesson Goals

  • To require uniqueness.
  • To work with keys.

Uniqueness

XML Schema provides a mechanism for requiring that each element be unique among like elements.

This is best illustrated with an example:

Code Sample:

SchemaKeys/Demos/Unique.xsd
---- C O D E   O M I T T E D ----
				<xs:element name="Artists">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="Artist" maxOccurs="unbounded">
								<xs:complexType>
									<xs:simpleContent>
										<xs:extension base="xs:string">
											<xs:attribute name="aID" type="xs:string" use="required"/>
										</xs:extension>
									</xs:simpleContent>
								</xs:complexType>
							</xs:element>
						</xs:sequence>
					</xs:complexType>
				</xs:element>
				<xs:element name="Lyrics">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="Stanza" maxOccurs="unbounded">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="Line" type="xs:string" maxOccurs="unbounded"/>
									</xs:sequence>
									<xs:attribute name="Artist" type="xs:string"/>
								</xs:complexType>
							</xs:element>
						</xs:sequence>
					</xs:complexType>
				</xs:element>
			</xs:sequence>
		</xs:complexType>
		<xs:unique name="ArtistKey">
			<xs:selector xpath="Artists/Artist"/>
			<xs:field xpath="@aID"/>
		</xs:unique>
	</xs:element>
</xs:schema>

The Artist element has an aID attribute, which we would like to be able to use to uniquely identify the artist. The XML Schema xs:unique element is used to enforce this. It takes two children:

  • xs:selector - takes an xpath attribute which holds an XPath 1.0 expression referencing the elements affected by this constraint.
  • xs:field - takes an xpath attribute which holds an XPath 1.0 expression specifying the part of the selected elements that must be unique.

In the example above, the selector XPath identifies all Artist elements that are children of an Artists element. The field XPath identifies the aID attribute as the part of the Artist element that must be unique.

In the XML instance below, each Artist must have a unique aID attribute. Try making them the same and validating.

Code Sample:

SchemaKeys/Demos/Unique.xml
<?xml version="1.0"?>
<Song xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Unique.xsd">
	<Title Type="duet">The Girl Is Mine</Title>
	<Year>1983</Year>
	<Length>Medium</Length>
	<Artists>
		<Artist aID="MJ">Michael Jackson</Artist>
		<Artist aID="PM">Paul McCartney</Artist>
	</Artists>
---- C O D E   O M I T T E D ----

</Song>

Keys

XML Schema also provides a mechanism for keys and key references - that is, for creating a relationship between elements through the value of an attribute or contained element. The xs:key and xs:keyref elements are used to create such a relationship.

Code Sample:

SchemaKeys/Demos/Keys.xsd
---- C O D E   O M I T T E D ----
				<xs:element name="Artists">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="Artist" maxOccurs="unbounded">
								<xs:complexType>
									<xs:simpleContent>
										<xs:extension base="xs:string">
											<xs:attribute name="aID" type="xs:string" use="required"/>
										</xs:extension>
									</xs:simpleContent>
								</xs:complexType>
							</xs:element>
						</xs:sequence>
					</xs:complexType>
				</xs:element>
				<xs:element name="Lyrics">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="Stanza" maxOccurs="unbounded">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="Line" type="xs:string" maxOccurs="unbounded"/>
									</xs:sequence>
									<xs:attribute name="Artist" type="xs:string" use="required"/>
								</xs:complexType>
							</xs:element>
						</xs:sequence>
					</xs:complexType>
				</xs:element>
			</xs:sequence>
		</xs:complexType>
		<xs:key name="ArtistKey">
			<xs:selector xpath="Artists/Artist"/>
			<xs:field xpath="@aID"/>
		</xs:key>
		<xs:keyref name="ArtistKeyRef" refer="ArtistKey">
			<xs:selector xpath="Lyrics/Stanza"/>
			<xs:field xpath="@Artist"/>
		</xs:keyref>
	</xs:element>
</xs:schema>

Like the xs:unique element, the xs:key and xs:keyref elements each contain xs:selector and xs:field child elements.

The xs:key element is used to identify the elements being referenced by the elements specified by the xs:keyref element.

In the example above, the Artist attribute of the Stanza element must point to an Artist element's aID attribute, which must be unique.

In the XML instance below, each Artist must have a unique aID attribute and each Stanza element must have an Artist attribute with the same value as one of the Artist's aID attributes. Try making changing the value of a Stanza's Artist attribute to something arbitrary and validating.

Code Sample:

SchemaKeys/Demos/Keys.xml
<?xml version="1.0"?>
<Song xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Keys.xsd">
	<Title Type="duet">The Girl Is Mine</Title>
	<Year>1983</Year>
	<Length>Medium</Length>
	<Artists>
		<Artist aID="MJ">Michael Jackson</Artist>
		<Artist aID="PM">Paul McCartney</Artist>
	</Artists>
	<Lyrics>
		<Stanza Artist="MJ">
			<Line>Every night she walks right in my dreams</Line>
			<Line>Every night she walks right in my dreams</Line>

---- C O D E   O M I T T E D ----
		</Stanza>
		<Stanza Artist="PM">
			<Line>I don't understand the way you think</Line>
			<Line>Saying that she's yours not mine</Line>

---- C O D E   O M I T T E D ----
		</Stanza>
		<Stanza Artist="MJ">
			<Line>I know she'll tell you I'm the one for her</Line>
			<Line>'Cause she said I blow her mind</Line>

---- C O D E   O M I T T E D ----
		</Stanza>
	</Lyrics>
</Song>