Datypic Logo
Definitive XML Schema

Definitive XML Schema

Priscilla Walmsley (pwalmsley@datypic.com)

2nd edition (September 2012)

Prentice Hall PTR; ISBN: 0132886723

Chapter 17: Identity constraints

Full Example

This example illustrates identity constraints. Each product element must have a number child whose value is unique within order. Each child of items must have a number attribute whose value matches one of these unique product numbers.

Instance (chapter17.xml)

<order xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation="chapter17.xsd">
  <number>123ABBCC123</number>
  <items>
    <shirt number="557">
      <quantity>1</quantity>
      <color value="blue"/>
    </shirt>
    <shirt number="557">
      <quantity>1</quantity>
      <color value="sage"/>
    </shirt>
    <hat number="563">
      <quantity>1</quantity>
    </hat>
  </items>
  <products>
    <product>
      <number>557</number>
      <name>Short-Sleeved Linen Blouse</name>
      <price currency="USD">29.99</price>
    </product>
    <product>
      <number>563</number>
      <name>Ten-Gallon Hat</name>
      <price currency="USD">69.99</price>
    </product>
  </products>
</order>

Schema (chapter17.xsd)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="order" type="OrderType">
    <xs:keyref name="prodNumKeyRef" refer="prodNumKey">
      <xs:selector xpath="items/*"/>
      <xs:field xpath="@number"/>
    </xs:keyref>
    <xs:key name="prodNumKey">
      <xs:selector xpath=".//product"/>
      <xs:field xpath="number"/>
    </xs:key>
  </xs:element>
  <xs:complexType name="OrderType">
    <xs:sequence>
      <xs:element name="number" type="xs:string"/>
      <xs:element name="items" type="ItemsType"/>
      <xs:element name="products" type="ProductsType"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ItemsType">
    <xs:choice maxOccurs="unbounded">
      <xs:element name="shirt" type="ProductOrderType"/>
      <xs:element name="hat" type="ProductOrderType"/>
    </xs:choice>
  </xs:complexType>
  <xs:complexType name="ProductOrderType">
    <xs:sequence>
      <xs:element name="quantity" type="xs:integer"/>
      <xs:element name="color" type="ColorType" minOccurs="0"/>
    </xs:sequence>
    <xs:attribute name="number" type="xs:integer"/>
  </xs:complexType>
  <xs:complexType name="ProductsType">
    <xs:sequence>
      <xs:element name="product" type="ProductType"
                   maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ProductType">
    <xs:sequence>
      <xs:element name="number" type="xs:integer"/>
      <xs:element name="name" type="xs:string"/>
      <xs:element name="price" type="PriceType"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ColorType">
    <xs:attribute name="value" type="xs:string"/>
  </xs:complexType>
  <xs:complexType name="PriceType">
    <xs:simpleContent>
      <xs:extension base="xs:decimal">
        <xs:attribute name="currency" type="xs:token"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
</xs:schema>

Book Examples

Example 17-1. Product catalog information

<catalog>
  <department number="021">
    <product>
      <number>557</number>
      <name>Short-Sleeved Linen Blouse</name>
      <price currency="USD">29.99</price>
    </product>
    <product>
      <number>563</number>
      <name>Ten-Gallon Hat</name>
      <price currency="USD">69.99</price>
    </product>
    <product>
      <number>443</number>
      <name>Deluxe Golf Umbrella</name>
      <price currency="USD">49.99</price>
    </product>
  </department>
</catalog>

Example 17-2. A uniqueness constraint

<xs:element name="catalog" type="CatalogType">
  <xs:unique name="prodNumKey">
    <xs:selector xpath="*/product"/>
    <xs:field xpath="number"/>
  </xs:unique>
</xs:element>

Example 17-3. Product catalog information, revisited

<catalog>
  <department number="021">
    <product effDate="2000-02-27">
      <number>557</number>
      <name>Short-Sleeved Linen Blouse</name>
      <price currency="USD">29.99</price>
    </product>
    <product effDate="2001-04-12">
      <number>557</number>
      <name>Short-Sleeved Linen Blouse</name>
      <price currency="USD">39.99</price>
    </product>
    <product effDate="2001-04-12">
      <number>563</number>
      <name>Ten-Gallon Hat</name>
      <price currency="USD">69.99</price>
    </product>
    <product>
      <number>443</number>
      <name>Deluxe Golf Umbrella</name>
      <price currency="USD">49.99</price>
    </product>
  </department>
</catalog>

Example 17-4. Constraining uniqueness of two combined fields

<xs:element name="catalog" type="CatalogType">
  <xs:unique name="dateAndProdNumKey">
    <xs:selector xpath="department/product"/>
    <xs:field xpath="number"/>
    <xs:field xpath="@effDate"/>
  </xs:unique>
</xs:element>

Example 17-5. Defining a key on product number

<xs:element name="catalog" type="CatalogType">
  <xs:key name="prodNumKey">
    <xs:selector xpath="*/product"/>
    <xs:field xpath="number"/>
  </xs:key>
</xs:element>

Example 17-6. Key references

<order>
  <number>123ABBCC123</number>
  <items>
    <shirt number="557">
      <quantity>1</quantity>
      <color value="blue"/>
    </shirt>
    <shirt number="557">
      <quantity>1</quantity>
      <color value="sage"/>
    </shirt>
    <hat number="563">
      <quantity>1</quantity>
    </hat>
  </items>
  <products>
    <product>
      <number>557</number>
      <name>Short-Sleeved Linen Blouse</name>
      <price currency="USD">29.99</price>
    </product>
    <product>
      <number>563</number>
      <name>Ten-Gallon Hat</name>
      <price currency="USD">69.99</price>
    </product>
  </products>
</order>

Example 17-7. Defining a key reference on product number

<xs:element name="order" type="OrderType">
  <xs:keyref name="prodNumKeyRef" refer="prodNumKey">
    <xs:selector xpath="items/*"/>
    <xs:field xpath="@number"/>
  </xs:keyref>
  <xs:key name="prodNumKey">
    <xs:selector xpath=".//product"/>
    <xs:field xpath="number"/>
  </xs:key>
</xs:element>

Example 17-8. Illegal uniqueness constraint

<xs:element name="catalog" type="CatalogType">
  <xs:unique name="prodNumKey">
    <xs:selector xpath="department"/>
    <xs:field xpath="product/number"/>
  </xs:unique>
</xs:element>

Example 17-9. Prefixing names in the XPath expression

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:prod="http://datypic.com/prod"
           targetNamespace="http://datypic.com/prod">
  <xs:element name="catalog" type="prod:CatalogType">
    <xs:unique name="dateAndProdNumKey">
      <xs:selector xpath="prod:department/prod:product"/>
      <xs:field xpath="prod:number"/>
      <xs:field xpath="@effDate"/>
    </xs:unique>
  </xs:element>
  <xs:element name="department" type="prod:DepartmentType"/>
  <xs:element name="product" type="prod:ProductType"/>
  <xs:element name="number" type="xs:integer"/>
  <!--...-->
</xs:schema>

Example 17-10. Illegal attempt to apply default namespace to XPath

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns="http://datypic.com/prod"
           targetNamespace="http://datypic.com/prod">
  <xs:element name="catalog" type="CatalogType">
    <xs:unique name="dateAndProdNumKey">
      <xs:selector xpath="department/product"/>
      <xs:field xpath="number"/>
      <xs:field xpath="@effDate"/>
    </xs:unique>
  </xs:element>
  <xs:element name="department" type="DepartmentType"/>
  <xs:element name="product" type="ProductType"/>
  <xs:element name="number" type="xs:integer"/>
  <!--...-->
</xs:schema>

Example 17-11. Using xpathDefaultNamespace

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns="http://datypic.com/prod"
           targetNamespace="http://datypic.com/prod"
           xpathDefaultNamespace="http://datypic.com/prod">
  <xs:element name="catalog" type="CatalogType">
    <xs:unique name="dateAndProdNumKey">
      <xs:selector xpath="department/product"/>
      <xs:field xpath="number"/>
      <xs:field xpath="@effDate"/>
    </xs:unique>
  </xs:element>
  <xs:element name="department" type="DepartmentType"/>
  <xs:element name="product" type="ProductType"/>
  <xs:element name="number" type="xs:integer"/>
  <!--...-->
</xs:schema>

Example 17-12. Referencing an identity constraint

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns="http://datypic.com/prod"
           targetNamespace="http://datypic.com/prod"
           xpathDefaultNamespace="http://datypic.com/prod">
  <xs:element name="catalog" type="CatalogType">
    <xs:unique name="dateAndProdNumKey">
      <xs:selector xpath="department/product"/>
      <xs:field xpath="number"/>
      <xs:field xpath="@effDate"/>
    </xs:unique>
  </xs:element>
  <xs:element name="discontinuedProductList" type="CatalogType">
    <xs:unique ref="dateAndProdNumKey"/>
  </xs:element>
  <!--...-->
</xs:schema>

Example 17-13. Referencing an identity constraint in a restriction

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://datypic.com/prod"
           xmlns="http://datypic.com/prod"
           xpathDefaultNamespace="http://datypic.com/prod">
  <xs:complexType name="CatalogListType">
    <xs:sequence>
      <xs:element name="catalog" type="CatalogType"
                  maxOccurs="unbounded">
        <xs:unique name="dateAndProdNumKey">
          <xs:selector xpath="department/product"/>
          <xs:field xpath="number"/>
          <xs:field xpath="@effDate"/>
        </xs:unique>
      </xs:element>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="RestrictedCatalogListType">
    <xs:complexContent>
      <xs:restriction base="CatalogListType">
        <xs:sequence>
          <xs:element name="catalog" type="CatalogType"
                      maxOccurs="1">
            <xs:unique ref="dateAndProdNumKey"/>
          </xs:element>
        </xs:sequence>
      </xs:restriction>
    </xs:complexContent>
  </xs:complexType>
  <!--...-->
</xs:schema>