6.6. Back to Our Library
Let's see where we can use our
Swiss army knife in our library. The first datatype, which we
promised to improve at the end of the last chapter, is the ISBN
number. Without fiddling the details of the constitution of an ISBN
number (which can't be fully checked with W3C XML
Schema), we can check that the total number of characters actually
used is 10 and limit its contents to digits and the letter
"X.":
<xs:simpleType name="isbn">
<xs:restriction base="xs:NMTOKEN">
<xs:length value="10"/>
<xs:pattern value="[0-9]{9}[0-9X]"/>
</xs:restriction>
</xs:simpleType>
TIP:
You may wonder why we kept the xs:length, since
as far as validation is concerned, it is less constraining than the
xs:pattern that we added. This is a question worth
asking, but it doesn't have a complete answer yet.
However, applications which use the PSVI as a source of meta
information may or may not be able to deduce from a pattern that the
length of a string has been fixed. It might be good practice to keep
redundant facets to provide extra information to these future
applications.
W3C XML Schema doesn't allow expression of the fact
that the book ID is the same value as the ISBN number with a
"b" used as a prefix, but we can
still define that it is a "b" with
9 digits and a trailing digit or
"X":
<xs:simpleType name="bookID">
<xs:restriction base="xs:ID">
<xs:pattern value="b\[0-9]{9}[0-9X]"/>
</xs:restriction>
</xs:simpleType>
To use this new datatype, we must be aware that we are using a
global attribute that was referenced in the
element book, but that was also referenced in the
elements character and author,
which do not have the same format. This is the main limitation in
using global elements and attributes: they can be referenced only if
they have the same types at all the locations in which they appear.
We can work around this problem by creating a local attribute
definition for the id attribute of
book with the new datatype.
The last things we may want to constrain are the dates for which no time zones are
needed and which, in fact, could just be a potential source of issues
if we need to compare them:
<xs:simpleType name="date">
<xs:restriction base="xs:date">
<xs:pattern value="[^:Z]*"/>
</xs:restriction>
</xs:simpleType>
Our new schema is then:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="string255">
<xs:restriction base="xs:token">
<xs:maxLength value="255"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="string32">
<xs:restriction base="xs:token">
<xs:maxLength value="32"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="isbn">
<xs:restriction base="xs:NMTOKEN">
<xs:length value="10"/>
<xs:pattern value="[0-9]{9}[0-9X]"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="bookID">
<xs:restriction base="xs:ID">
<xs:pattern value="b\d[0-9]{9}[0-9X]"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="supportedLanguages">
<xs:restriction base="xs:language">
<xs:enumeration value="en"/>
<xs:enumeration value="es"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="date">
<xs:restriction base="xs:date">
<xs:pattern value="[^:Z]*"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="name" type="string32"/>
<xs:element name="qualification" type="string255"/>
<xs:element name="born" type="date"/>
<xs:element name="dead" type="date"/>
<xs:element name="isbn" type="isbn"/>
<xs:attribute name="id" type="xs:ID"/>
<xs:attribute name="available" type="xs:boolean"/>
<xs:attribute name="lang" type="supportedLanguages"/>
<xs:element name="title">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="string255">
<xs:attribute ref="lang"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="library">
<xs:complexType>
<xs:sequence>
<xs:element ref="book" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="author">
<xs:complexType>
<xs:sequence>
<xs:element ref="name"/>
<xs:element ref="born"/>
<xs:element ref="dead" minOccurs="0"/>
</xs:sequence>
<xs:attribute ref="id"/>
</xs:complexType>
</xs:element>
<xs:element name="book">
<xs:complexType>
<xs:sequence>
<xs:element ref="isbn"/>
<xs:element ref="title"/>
<xs:element ref="author" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="character" minOccurs="0"
maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="id" type="bookID"/>
<xs:attribute ref="available"/>
</xs:complexType>
</xs:element>
<xs:element name="character">
<xs:complexType>
<xs:sequence>
<xs:element ref="name"/>
<xs:element ref="born"/>
<xs:element ref="qualification"/>
</xs:sequence>
<xs:attribute ref="id"/>
</xs:complexType>
</xs:element>
</xs:schema>
 |  |  | | 6.5. Common Patterns |  | 7. Creating Complex Datatypes |
Copyright © 2002 O'Reilly & Associates. All rights reserved.
|