Namespace Behavior of Imported Components

You may be wondering about the different approaches used to identify the namespaces for the elements defined by the schema and the data types defined by W3C XML Schema. Importing schemas imposes certain restrictions on the use of namespaces in the imported schema.

When we define an element or attribute, we give it a namespace. That namespace must be the same as the target namespace of the schema doing the importing, even if the datatype of the element or attribute belongs to a different namespace.

The rules are slightly different when we define an element or attribute by reference to a component which is in a different namespace, rather than a datatype. In that case, the name of the referenced component is imported, and that namespace must be the target namespace of the imported schema.

To illustrate how this works, we’ll take a closer look at two ways to create schemas described in this simple example:

<?xml version="1.0"?>
<!-- Namespace: http://dyomedea.com/ns/library --> 
<library xmlns:ppl="http://dyomedea.com/ns/people"
  xmlns="http://dyomedea.com/ns/library">
  <book id="b0836217462">
    <title>
      Being a Dog Is a Full-Time Job
    </title>
    <authors>
      <ppl:person id="CMS">
        <ppl:name>
          Charles M Schulz
        </ppl:name>
      </ppl:person>
    </authors>
  </book>
</library>

This document contains two namespaces. Everything except the contents of the authors element is in the http://dyomedea.com/ns/library namespace. The contents of the authors element (ppl:person and ppl:name) are in the http://dyomedea.com/ns/people namespace.

We have two main options for representing this document using W3C XML Schema. Both approaches start by defining a schema for the elements in the http://dyomedea.com/ns/library namespace. The first approach imports the schema defining the http://dyomedea.com/ns/people namespace, and then uses a reference to the ppl:person element to use it inside the authors element:

<?xml version="1.0"?> 
<xs:schema targetNamespace="http://dyomedea.com/ns/library"
  elementFormDefault="qualified" attributeFormDefault="unqualified"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:ppl="http://dyomedea.com/ns/people"
  xmlns:lib="http://dyomedea.com/ns/library"> 
  <xs:import namespace="http://dyomedea.com/ns/people"
    schemaLocation="very-simple-2-ns-ppl.xsd"/>
  <xs:element name="library">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="book" type="lib:bookType"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="bookType">
    <xs:sequence>
      <xs:element name="title" type="xs:string"/>
      <xs:element name="authors">
        <xs:complexType>
          <xs:sequence>
            <xs:element ref="ppl:person"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
    <xs:attribute name="id" type="xs:ID" use="required"/>
  </xs:complexType>
</xs:schema>

The second approach does the same import, but defines the authors element as having the type ppl:authorType rather than defining its complex type explicitly, resulting in a shorter schema:

<?xml version="1.0"?> 
<xs:schema targetNamespace="http://dyomedea.com/ns/library"
  elementFormDefault="qualified" attributeFormDefault="unqualified"
  xmlns:lib="http://dyomedea.com/ns/library"
  xmlns:ppl="http://dyomedea.com/ns/people"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
  <xs:import namespace="http://dyomedea.com/ns/people"
    schemaLocation="very-simple-2-ns-ppl.xsd"/>
  <xs:element name="library">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="book" type="lib:bookType"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="bookType">
    <xs:sequence>
      <xs:element name="title" type="xs:string"/>
      <xs:element name="authors" type="ppl:authorType"/>
    </xs:sequence>
    <xs:attribute name="id" type="xs:ID" use="required"/>
  </xs:complexType>
</xs:schema>

Although the two schemas will validate the same instance documents, the design style is quite different. Applications relying on the schema for information about the document will see it in two very different ways. The first approach provides a cleaner separation between the two namespaces. The use of the reference allows the ppl:person element to appear inside the authors element but does nothing to mix the authors element with the http://dyomedea.com/ns/people namespace directly. The second approach is briefer, but assigns a datatype in one namespace to an element in another namespace.

If you are using your schemas purely for validation, this distinction is unimportant. Both schemas will validate identical sets of documents. If, however, your applications rely on your schemas for type information (using the PSVI or perhaps compile-time data-binding based on the schema), the perspective shift may matter. Using the datatype approach will mean that your applications need to understand quite a bit more about the contents of your schema and creates new dependencies between your application and the details of W3C XML Schema processing.