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

advertisement

Using W3C XML Schema
by Eric van der Vlist | Pages: 1, 2, 3, 4, 5, 6, 7, 8, 9

Table of Contents

Introducing Our First Schema
Slicing the Schema
Defining Named Types
Groups, Compositors and Derivation
Content Types
Constraints
Building Usable and Reusable Schemas
Namespaces
W3C XML Schema and Instance Documents
W3C XML Schema Datatypes Reference
W3C XML Schema Structures Reference

Namespaces

Namespaces support in W3C XML Schema is flexible yet straightforward. It not only allows the use of any prefix in instance documents (unlike DTDs) but also lets you open your schemas to accept unknown elements and attributes from known or unknown namespaces.

Each W3C XML Schema document is bound to a specific namespace through the targetNamespace attribute, or to the absence of namespace through the lack of such an attribute. We need at least one schema document per namespace we want to define (elements and attributes without namespaces can be defined in any schema, though).

Until now we have omitted the targetNamespac attribute, which means that we were working without namespaces. To get into namespaces, let's first imagine that our example belongs to a single namespace:

<book isbn="0836217462" xmlns="http://example.org/ns/books/">
 .../...
</book>

The least intrusive way to adapt our schema is to add some more attributes to our xs:schema element.

<xs:schema targetNamespace="http://example.org/ns/books/" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:bk="http://example.org/ns/books/" 
    elementFormDefault="qualified"
    attributeFormDefault="unqualified">
    .../...
</xs:schema>

The namespace declarations play an important role. The first one (xmlns:xs="http://www.w3.org/2001/XMLSchema") says not only that we've chosen to use the prefix xs to identify the elements that will be W3C XML Schema instructions, but also that we will prefix the W3C XML Schema predefined datatypes with xs as we have done all over the examples thus far. Understand that we could have chosen any prefix instead of xs. We could even make http://www.w3.org/2001/XMLSchema our default namespace and in this case, we wouldn't have prefixed the W3C XML Schema elements nor its datatypes.

Since we are working with the http://example.org/ns/books/ namespace, we define it (with a bk prefix). This means that we will now prefix the references to "objects" (datatypes, elements, attributes, ...) belonging to this namespace with bk:. Again, we could have chosen any prefix to identify this namespace or even have made it our default namespaces (note that the XPath expressions used in xs:unique, xs:key and xs:keyref do not use a default namespace, though).

The targetNamespace attribute lets you define, independently of the namespace declarations, which namespace is described in this schema. If you need to reference objects belonging to this namespace, which is usually the case except when using a pure "Russian doll" design, you need to provide a namespace declaration in addition to the targetNamespace.

The final two attributes (elementFormDefault and attributeFormDefault) are a facility provided by W3C XML Schema to control, within a single schema, whether attributes and elements are considered by default to be qualified (in a namespace). This differentiation between qualified and unqualified can be indicated by specifying the default values, as above, but also when defining the elements and attributes, by adding a form attribute of value qualified or unqualified.

It is important to note that only local elements and attributes can be specified as unqualified. All globally defined elements and attributes must always be qualified.

Importing definitions from external namespaces

W3C XML Schema, not unlike XSLT and XPath, uses namespace prefixes within the value of some attributes to identify the namespace of data types, elements, attributes, atc. For instance, we've used this feature all along our examples to identify the W3C XML Schema predefined datatypes. This mechanism can be extended to import definitions from any other namespace and so reuse them in our schemas.

Reusing definitions from other namespaces is done through a three-step process. This process needs to be done even for the XML 1.0 namespace, in order to declare attributes such as xml:lang. First, the namespace must be defined as usual.

<xs:schema targetNamespace="http://example.org/ns/books/" 
  xmlns:xml="http://www.w3.org/XML/1998/namespace" 
  xmlns:bk="http://example.org/ns/books/" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  elementFormDefault="qualified"
  attributeFormDefault="qualified">
  .../...
</xs:schema>

Then W3C XML Schema needs to be informed of the location at which it can find the schema corresponding to the namespace. This is done using an xs:import element.

<xs:import namespace="http://www.w3.org/XML/1998/namespace"
  schemaLocation="myxml.xsd"/>

W3C XML Schema now knows that it should attempt to find any reference belonging to the XML namespace in a schema located at myxml.xsd. We can now use the external definition.

   <xs:element name="title">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base="xs:string">
          <xs:attribute ref="xml:lang"/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

You may wonder why we have chosen to reference the xml:lang attribute from the XML namespace, rather than creating an attribute with a type xml:lang. We've done so because there is an important difference between referencing an attribute (or an element) and referencing a datatype when namespaces are concerned:

  • Referencing an element or an attribute imports the whole thing with its name and namespace,
  • Referencing a datatype imports only its definition, leaving you with the task of giving a name to the element and attribute you're defining and using the target namespace (or no namespace if your attribute or element is unqualified).

Including unknown elements

To finish this section about namespaces, we need to see how, as promised in our introduction, we can open our schema to unknown elements, attributes and namespaces. This is done using xs:any and xs:anyAttribute, allowing, respectivly, to include any elements or attributes.

For instance, if we want to extend the definition of our description type to any XHTML tag, we could declare:

<xs:complexType name="descType" mixed="true">
  <xs:sequence>
    <xs:any namespace="http://www.w3.org/1999/xhtml" 
	  processContents="skip" minOccurs="0"
	  maxOccurs="unbounded"/>
  </xs:sequence>
</xs:complexType>

The xs:anyAttribute gives the same functionality for attributes.

The type descType is now mixed content and accepts an unbounded number of any element from the http://www.w3.org/1999/xhtml namespace. The processContents attribute is set to skip telling a W3C XML Schema processor that no validation of these elements should be attempted. The other permissible values could are strict asking to validate these elements or lax asking to validate them when possible. The namespace attribute accepts a whitespace-separated list of URIs and the special values ##local (non qualified elements) and ##targetNamespace (the target namespace) that can be included in the list and ##other (any namespace other than the target) or ##any (any namespace) that can replace the list. It is not possible to specify any namespace except those from a list.

Pages: 1, 2, 3, 4, 5, 6, 7, 8, 9

Next Pagearrow