XML.com: XML From the Inside Out
oreilly.comSafari Bookshelf.Conferences.


Using W3C XML Schema - Part 2
by Eric van der Vlist | Pages: 1, 2, 3, 4, 5

Building Usable -- and Reusable -- Schemas

Table of Contents

Content Types
Building Usable and Reusable Schemas
W3C XML Schema and Instance Documents

Perhaps the first step in writing reusable schemas is to document them. W3C XML Schema provides an alternative to XML comments and processing instructions that might be easier to handle for supporting tools.

Human readable documentation can be defined by xsd:documentation elements, while information targeted at applications should be included in xsd:appinfo elements. Both elements must be included in an xsd:annotation element. They accept optional xml:lang and source attributes. The source attribute is a URI reference that can be used to indicate the purpose of the appinfo to the processing application.

The xsd:annotation elements can be added at the beginning of most schema constructs as shown in example below. The appinfo section demonstrates how custom namespaces and schemes might allow the binding of an element to a Java class from within the schema.

<xsd:element name="book">
    <xsd:documentation xml:lang="en">
      Top level element.
    <xsd:documentation xml:lang="fr">
      Element racine.
    <xsd:appinfo source="http://example.com/foo/">
      <bind xmlns="http://example.com/bar/">
        <class name="Book"/>

Composing schemas from multiple files

For those who want to define a schema using several XML documents -- either to split up a large schema or to use libraries of schema snippets -- W3C XML Schema provides two mechanisms for including external schemas.

The first, xsd:include, is similar to a copy and paste of the definitions of the included schema: it's an inclusion, and as such it doesn't allow any overriding of definitions of the included schema. It can be used in this way:

<xsd:include schemaLocation="character.xsd"/> 

The second inclusion mechanism, xsd:redefine, is similar to xsd:include, except that it lets you redefine the declarations from the included schema.

<xsd:redefine schemaLocation="character12.xsd">
<xsd:simpleType name="nameType">
 <xsd:restriction base="xsd:string">
  <xsd:maxLength value="40"/>

Note that the declarations that are redefined must be placed in the xsd:redefine element.

We've already seen many features that can be used together with xsd:include and xsd:redefine to create libraries of schemas. We've seen how we can reference previously defined elements; how we can define datatypes by derivation and use them; and how we can define and use groups of attributes. We've also seen the parallel between elements and objects and datatypes and classes. There are other features borrowed from object oriented design that can be used to create reusable schemas.

Abstract types

The first feature derived from object oriented design is the substitution group. Unlike the features we've seen so far, a substitution group isn't defined explicitly through a W3C XML Schema element but through referencing a common element (called the head), using a substitutionGroup attribute. The head element doesn't hold any specific declaration but must be global. All the elements within a substitution group need to have a type that is either the same type as the head element, or can be derived from it. Then they can all be used in place of the head element. In the following example the element "surname" can be used anywhere an element "name" has been defined.

<xsd:element name="name" type="xsd:string"/>
<xsd:element name="surname" type="xsd:string" substitutionGroup="name" />

Now we can also define a generic "name-elt" element, head of a substitution group, that couldn't be used directly but should be used in one of its derived forms. This is done through declaring the element as abstract, analagously to abstract classes in object oriented languages. The following example defines name-elt as an abstract element that should be replaced by either name or surname everywhere it is referenced.

<xsd:element name="name-elt" type="xsd:string" abstract="true"/>
<xsd:element name="name" type="xsd:string" substitutionGroup="name-elt" />
<xsd:element name="surname" type="xsd:string" substitutionGroup="name-elt" />

Final types

We could, on the other hand, wish to control derivation performed on a datatype. W3C XML Schema supports this though the final attribute in an xsd:complexType or xsd:element element. This attribute can take the values restriction, extension and #all to block derivation by restriction, extension or any derivation. The following snippet would, for instance, forbid any derivation of the characterType complex type.

<xsd:complexType name="characterType" final="#all">

The final attribute can operate only on elements and complex types. W3C XML Schema provides a fine-grained mechanism that operates on each facet to control the derivation of simple types. This attribute is called fixed, and when its value is set to true, the facet cannot be further modified (but other facets can still be added or modified). The following prevents the size of our nameType simple type from being redefined.

<xsd:simpleType name="nameType">
 <xsd:restriction base="xsd:string">
  <xsd:maxLength value="32" fixed="true"/>

Pages: 1, 2, 3, 4, 5

Next Pagearrow