Book HomeXML SchemaSearch this book

7.7. Back to Our Library

We've covered so much ground in this chapter that it's not obvious which features could be the most beneficial! This choice also depends on external factors such as the level of W3C XML Schema support available from the tools that will be used. For instance, some tools that produce Java classes or binding may take advantage of complex type derivation by restriction. This is the path we will follow for now. We will create a complex type complex content, which will be a superset of the content models of author and character, which we will derive by restriction. First, we can also define an empty content model with an id attribute, which can be derived by extension for all the content models that have an id attribute:

<xs:complexType name="elementWithID">
  <xs:attribute ref="id"/>
</xs:complexType>

Note that we cannot use this type directly to define the book element, since its id attribute is a restriction of xs:ID:

<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>

To use our elementWithID complex type to define the book element, we need to derive by extension a complex type corresponding to the complex type of book without the restriction on the id attribute. The following code is quite verbose, but it is shown here as an exercise:

<xs:complexType name="bookTmp">
  <xs:complexContent>
    <xs:extension base="elementWithID">
      <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 ref="available"/>
    </xs:extension>
  </xs:complexContent>
</xs:complexType>
       
<xs:element name="book">
  <xs:complexType>
    <xs:complexContent>
      <xs:restriction base="bookTmp">
        <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:restriction>
    </xs:complexContent>
  </xs:complexType>
</xs:element>

A more concise option is to derive by restriction first:

<xs:complexType name="elementWithBookID">
  <xs:complexContent>
    <xs:restriction base="elementWithID">
      <xs:attribute name="id" type="bookID"/>
    </xs:restriction>
  </xs:complexContent>
</xs:complexType>


<xs:complexType name="book">
  <xs:complexContent>
    <xs:extension base="elementWithBookID">
      <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 ref="available"/>
    </xs:extension>
  </xs:complexContent>
</xs:complexType>

Using the elementWithID to derive by extension a personType, which can then be used to derive the author and character elements by restriction, is straightforward, if not concise. We have already seen this example. The full 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:totalDigits 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[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:complexType name="elementWithID">
    <xs:attribute ref="id"/>
  </xs:complexType>
  <xs:complexType name="bookTmp">
    <xs:complexContent>
      <xs:extension base="elementWithID">
        <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 ref="available"/>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:complexType name="personType">
    <xs:complexContent>
      <xs:extension base="elementWithID">
        <xs:sequence>
          <xs:element ref="name"/>
          <xs:element ref="born"/>
          <xs:element ref="dead" minOccurs="0"/>
          <xs:element ref="qualification" minOccurs="0"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <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="book">
    <xs:complexType>
      <xs:complexContent>
        <xs:restriction base="bookTmp">
          <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:restriction>
      </xs:complexContent>
    </xs:complexType>
  </xs:element>
  <xs:element name="author">
    <xs:complexType>
      <xs:complexContent>
        <xs:restriction base="personType">
          <xs:sequence>
            <xs:element ref="name"/>
            <xs:element ref="born"/>
            <xs:element ref="dead" minOccurs="0"/>
          </xs:sequence>
          <xs:attribute ref="id"/>
        </xs:restriction>
      </xs:complexContent>
    </xs:complexType>
  </xs:element>
  <xs:element name="character">
    <xs:complexType>
      <xs:complexContent>
        <xs:restriction base="personType">
          <xs:sequence>
            <xs:element ref="name"/>
            <xs:element ref="born"/>
            <xs:element ref="qualification"/>
          </xs:sequence>
          <xs:attribute ref="id"/>
        </xs:restriction>
      </xs:complexContent>
    </xs:complexType>
  </xs:element>
</xs:schema>


Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.