First, the new addressBook element is declared,
including a key based on the ssn attribute of each
address entry:
<xs:element name="addressBook">
<xs:complexType>
<xs:sequence maxOccurs="unbounded">
<xs:element ref="addr:address"/>
</xs:sequence>
</xs:complexType>
<xs:key name="ssnKey">
<xs:selector xpath="addr:address"/>
<xs:field xpath="@addr:ssn"/>
</xs:key>
</xs:element>
Now that the key is defined, you can add a new element to the
address element declaration that connects a
particular address record with another record. For example, to list
references to the children of a particular person in the address
book, add the following declaration for a kids
element:
<xs:element name="address">
<xs:complexType>
<xs:sequence>
<xs:element name="fullName">
. . .
</xs:element>
<xs:element name="kids" minOccurs="0">
<xs:complexType>
<xs:sequence maxOccurs="unbounded">
<xs:element name="kid">
<xs:complexType>
<xs:attribute name="ssn" type="addr:ssn"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
. . .
</xs:sequence>
<xs:attributeGroup ref="addr:nationality"/>
<xs:attribute name="ssn" type="addr:ssn"/>
<xs:anyAttribute namespace="http://www.w3.org/1999/xlink"
processContents="skip"/>
</xs:complexType>
</xs:element>
Now, an xs:keyref element in the
addressBook element declaration enforces the
constraint that the ssn attribute of a particular
kid element must match an ssn
attribute on an address element in the current
document:
<xs:element name="addressBook">
. . .
<xs:key name="ssnKey">
<xs:selector xpath="addr:address"/>
<xs:field xpath="@addr:ssn"/>
</xs:key>
<xs:keyref name="kidSSN" refer="addr:ssnKey">
<xs:selector xpath="addr:address/kids/kid"/>
<xs:field xpath="@addr:ssn"/>
</xs:keyref>
</xs:element>