9.4. Using xs:key and xs:unique As Co-occurrence Constraints
Co-occurrence
constraints
are
interdependent conditions given on the child elements or attributes
of a node, such as "if this element is present, then
this attribute must be absent." Under-implemented
within W3C XML Schema, these constraints can be a workaround to the
"Consistent Declaration
rule," which forbids definition of two different
content models for an element at the same location in an instance
document. With co-occurrence constraints, one can define a superset
of the two content models and add the constraints to forbid the
unwanted combinations. This is frequently useful with vocabularies
(such as RDF) in which some properties can be expressed either as an
attribute or an element, and in which we may want to extend our book
example to accept the ISBN number and the title to be expressed as
elements or attributes. The two following
instance documents are then valid (with
their two remaining combinations):
<book id="b0836217462" available="true">
<isbn>
0836217462
</isbn>
<title lang="en">
Being a Dog Is a Full-Time Job
</title>
../..
</book>
or:
<book id="b0836217462" available="true" isbn="0836217462"
title="Beinga Dog Is a Full-Time Job">
.../...
</book>
The obvious way is to define the book element as a
choice between the four different valid content models (with the four
combinations of elements and attributes). However, this is forbidden
by the Consistent Declaration rule, which states that only one
content model may be used for
a given element. The workaround is to define a content model that
accepts both optional elements and attributes:
<xs:complexType>
<xs:sequence>
<xs:element ref="isbn" minOccurs="0"/>
<xs:element ref="title" minOccurs="0"/>
<xs:element ref="author" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="character" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute ref="id"/>
<xs:attribute ref="available"/>
<xs:attribute ref="isbn"/>
<xs:attribute ref="title"/>
</xs:complexType>
This definition allows instance documents with both a
title (or isbn) element and
attribute or instance documents without any title
or isbn at all. We need to add co-occurrence
constraints. In a more general case, these constraints cannot be
expressed using W3C XML Schema, and we need to embed other languages
(as shown in Chapter 14, "Documenting Schemas") but when we think about
it, xs:unique, xs:key, and xs:keyref can be considered very specific
co-occurrence constraints and they can be used here. If we want to
insure that we have only one title and ISBN number, we can add a
xs:key definition in the
book element itself:
<xs:key name="isbn">
<xs:selector xpath="."/>
<xs:field xpath="isbn|@isbn"/>
</xs:key>
<xs:key name="title">
<xs:selector xpath="."/>
<xs:field xpath="title|@title"/>
</xs:key>
These keys are evaluated in the scope of a book element and
won't have any effect outside each book element.
They will consider the book invalid if the XPath expression in their
field element returns either no nodes or multiple
nodes. Note that if we had used xs:unique instead of xs:key, we would still have required that
only one of the elements or attributes be present, but that would
have made the property optional. For the record, the full definition
of our book element would then be:
<xs:element name="book">
<xs:complexType>
<xs:sequence>
<xs:element ref="isbn" minOccurs="0"/>
<xs:element ref="title" minOccurs="0"/>
<xs:element ref="author" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="character" minOccurs="0"
maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute ref="id"/>
<xs:attribute ref="available"/>
<xs:attribute ref="isbn"/>
<xs:attribute ref="title"/>
</xs:complexType>
<xs:key name="isbn">
<xs:selector xpath="."/>
<xs:field xpath="isbn|@isbn"/>
</xs:key>
<xs:key name="title">
<xs:selector xpath="."/>
<xs:field xpath="title|@title"/>
</xs:key>
</xs:element>
 |  |  | 9.3. ID/IDREF Versus / |  | 10. Controlling Namespaces |
Copyright © 2002 O'Reilly & Associates. All rights reserved.
|