Chapter 10. Controlling Namespaces

The W3C released Namespaces in XML about a year after XML 1.0. Namespaces provide a URI-based mechanism that helps differentiate XML vocabularies. Rather than update XML 1.0’s DTDs to provide explicit namespace support, the W3C chose to implement namespace support in W3C XML Schema. Support of namespaces was eagerly awaited by the XML community and, thus, are especially well-polished by the W3C XML Schema editors.

Namespaces caused two problems to DTDs. One was how to recognize namespaces defined using different prefixes in instance documents. The other was how best to facilitate the definition of schemas with multiple namespaces. The problem of open schemas tightly controlling some namespaces while keeping the flexibility to add unknown elements and attributes from unknown namespaces, was especially difficult.

W3C XML Schema has gone beyond these expectations for its use of namespaces by associating a namespace to all the objects (elements and attributes, but also simple and complex types as well as groups of elements and attributes) defined in a schema, allowing the use of namespaces to build modular libraries of schemas.

Namespaces Present Two Challenges to Schema Languages

Namespace prefixes should only be considered to be local shortcuts to replace the URI references that are the real identifiers for a namespace. The following documents should, therefore, be considered strictly equivalent by namespace-aware applications:

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

In the document above, the namespace "http://dyomedea.com/ns/library" is defined as the default namespace and applies to all the elements within the document. Next, we’ll show a namespace-equivalent, but very different-looking, document:

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

The namespace "http://dyomedea.com/ns/library" is defined as mapping to the prefix lib and is used as a prefix for all the elements within the document. Next, we’ll create another namespace-equivalent document using a different prefix.

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

The namespace "http://dyomedea.com/ns/library" is defined as mapping to the prefix l and is used as a prefix for all the elements within the document. Finally, we’ll mix all of these possibilities in a single document still namespace-equivalent to the others.

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

The same namespace is defined and used as l, lib, and even as a default namespace, depending on its location in the document. This last example is, of course, an extreme case that isn’t recommended. This document conforms to the namespaces recommendation, however, and the specification states that it is strictly equivalent to the three previous ones.

DTDs are not aware of the namespaces. Since the colon (:) is allowed in the XML names, lib:person, l:person, and person are three different, valid names for a DTD. Furthermore, a DTD sees namespace declaration attributes (xmlns, xmlns:l, xmlns:lib) as ordinary attributes that need to be declared.

A XML document using namespaces is a well-formed XML 1.0 document and it is perfectly possible to write a DTD to describe it. Nevertheless, you must define the prefixes that can be used and the location where the namespace declarations must be inserted. This is acceptable only if you can fully control or specify the authoring processes of the documents.

The second and larger issue is design. Since XML is often used as the glue between different applications, it is becoming increasingly important to be able to define modular vocabularies that can live together in the same document, and namespaces were invented to make this possible. To take advantage of this feature, it is often necessary to define open vocabularies that will define places where external elements and attributes from external namespaces may be included without breaking the applications.

Imagine a marketing department wants to add the type of cover and the number of pages to the information about a particular book. A neat way to do this—if this new information is specific to their needs and we don’t want to break the existing applications—is to create a new namespace:

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

However, if we want to keep our schema independent of the marketing application, we need a flexible way to open it and say “accept any element from the marketing namespace at the end of our book element.” Also, even if there might be other applications that work with our vocabulary, we can say to accept any element from any other namespace at the end of our book element.

Namespace Declarations

Until now, we have seen schemas for documents that had no namespace declarations of any kind and, therefore, did not belong to any namespace. To match the documents without namespaces, the schemas had no namespace declaration either, except the one needed to identify the W3C XML Schema namespace itself.

To match the elements and attributes that belong to a namespace, we need to associate this namespace with our schema through the targetNamespace attribute of the xs:schema element.

If we modify our library to use a single namespace:

<library xmlns="http://dyomedea.com/ns/library">
  <book id="b0836217462" available="yes">
    <isbn>
      0836217462
    </isbn>
    <title>
      Being a Dog Is a Full-Time Job
    </title>
    .../...
  </book>
</library>

We need to modify our schema to declare the namespace and to define it as the target namespace:

<xs:schema targetNamespace="http://dyomedea.com/ns/library"
  elementFormDefault="qualified" attributeFormDefault="unqualified"
  xmlns:lib="http://dyomedea.com/ns/library"
  xmlns:xs="http://www.w3.org/2001/XMLSchema">
  .../...
</xs:schema>

The definition of the namespaces is especially important here, since W3C XML Schema uses them for two purposes.

As for any XML document that conforms to the namespaces Recommendation, the first purpose of the namespace declaration is to associate a URI reference that is the identifier of a namespace to a prefix, which is a shortcut for this identifier.

In our example, we have two such declarations: xmlns:xs="http://www.w3.org/2001/XMLSchema" and xmlns:lib="http://dyomedea.com/ns/library".

The first declaration associates the W3C XML Schema namespace with the prefix xs. We could, of course, have chosen any prefix, or even used this namespace as the default namespace; the choice of xs is just common usage.

The second declaration defines the namespace used in our instance document, xmlns:lib="http://dyomedea.com/ns/library". Here we chose to use the lib prefix, even though this namespace is never used for any element or attribute of the schema itself. We could also have chosen any prefix for this namespace, or even have defined it as our default namespace.

This second declaration is needed for the second usage of namespace prefixes. W3C XML Schema uses the namespace prefixes to resolve all the references to the components of a schema (datatypes, elements, attributes, groups, etc.), as well as for the XPath expressions used in the xs:unique , xs:key , and xs:keyref declarations.

We haven’t yet mentioned which namespace this schema describes. We must do so using the targetNamespace attribute that defines the URI reference that identifies the target namespace.

With this last piece of information, a schema processor knows what the target namespace is. With the two namespaces declarations already complete, it also knows which prefix we want to use for it and for the W3C XML Schema namespace. This is sufficient information to write our schema.

Note

This use of the namespace prefixes, common to W3C XML Schema and XSLT, is very controversial, since it creates a dependency between W3C XML Schema (considered an application) and the prefixes chosen for the namespaces. This breaks the layered structure of the XML specifications: the markup and its content become interdependent and cannot be changed independently any longer.

Not unlike a communication protocol, the XML specifications may be seen as a set of envelopes. XML 1.0 is the outermost envelope into which the namespaces are included. While the applications should be independent of these envelopes, the fact that W3C XML Schema is making use of the namespace prefixes inside its own attributes glues the schema to its envelope. This is a very dangerous practice that should be discouraged for other vocabularies that define their own sets of prefixes.

One of the consequences of this practice is that Canonical XML has been obliged to remove namespace prefix rewriting from its requirements, meaning that the four flavors of our library that are strictly equivalent, per the namespace recommendation, will have four different canonical values, and different digital signatures as a result.

To Qualify Or Not to Qualify?

The schemas that we have written up to this point have had no target namespace declaration. We also could only describe elements and attributes that didn’t belong to any namespace.

The declaration of a target namespace gives us the possibility of defining elements and attributes that belong to the target namespace (called “qualified”) and elements and attributes that don’t belong to any namespace (called “unqualified”).

Tip

The purpose of a schema is to describe a vocabulary, in which top-level nodes belong to its target namespace. For this reason, it is forbidden to define global elements that are unqualified when a target namespace is declared.

The distinction between qualified and unqualified elements and attributes is made through their <form> attributes—for example:

<xs:element name="book" form="qualified"/>
  
<xs:attribute name="isbn" form="qualified"/>
  
<xs:attribute name="lang" form="unqualified"/>
  
<xs:element name="character" form="unqualified"/>

The default values of these form attributes are defined in the elementFormDefault and attributeFormDefault attributes that we have added in our xs:schema element.

These attributes both have default values of their own, which are: elementFormDefault="unqualified" and attributeFormDefault="unqualified". These values are appropriate to the case in which only the document element uses a namespace:

<lib:library xmlns:lib="http://dyomedea.com/ns/library">
  <book id="b0836217462" available="yes">
    <isbn>
      0836217462
    </isbn>
    <title>
      Being a Dog Is a Full-Time Job
    </title>
  </book>
</lib:library>

Since global elements and attributes must be qualified, defining this schema as a single schema requires that all the elements and attributes are locally defined.

Another combination, elementFormDefault="qualified" and attributeFormDefault="unqualified" matches the common case in which a namespace is attached to the root element as the default namespace that will, by definition apply to the included elements but not to the attributes. (Per the Namespaces Recommendation, the default namespace does not apply to attributes.)

<library xmlns="http://dyomedea.com/ns/library">
  <book id="b0836217462" available="yes">
    <isbn>
      0836217462
    </isbn>
    <title>
      Being a Dog Is a Full-Time Job
    </title>
  </book>
</library>

The usage considers that unqualified attributes belong to the same vocabulary as their parent element, and the vocabularies that take advantage of qualified attributes are often vocabularies that supply attributes used in elements from other namespaces. Examples of such vocabularies include RDF and attribute-only vocabularies such as XLink and XML Base. The schemas for these vocabularies will benefit from an attributeFormDefault set to qualified.

One should pay attention to the special status of the attributes in the namespace specification. The default namespace does not apply to attributes. This means that an attribute without a prefix is considered to have no namespace.

Another confusing aspect of attributes with a prefix (which thus belong to a namespace) is these attributes are called "global attributes” in the namespaces recommendation. In W3C XML Schema the term global is used differently, in opposition to local elements or attributes. A global attribute, per namespaces, is therefore a qualified attribute per W3C XML Schema, and may be globally or locally defined.

Tip

Remember that <elementFormDefault> and <attributeFormDefault> define default values and that you can specify—element by element and attribute by attribute—if they are qualified or not.

Before we see how we can bring more namespaces into the game, let’s look at a simple instance document with a single namespace and unqualified attributes:

<?xml version="1.0"?>
<library xmlns="http://dyomedea.com/ns/library">
  <book id="b0836217462" available="yes">
    <isbn>
      0836217462
    </isbn>
    <title>
      Being a Dog Is a Full-Time Job
    </title>
    <authors>
      <person id="CMS">
        <name>
          Charles M Schulz
        </name>
        <born>
          1922-11-26
        </born>
        <dead>
          2000-02-12
        </dead>
      </person>
    </authors>
    <characters>
      <person id="PP">
        <name>
          Peppermint Patty
        </name>
        <born>
          1966-08-22
        </born>
        <qualification>
          bold, brash and tomboyish
        </qualification>
      </person>
      <person id="Snoopy">
        <name>
          Snoopy
        </name>
        <born>
          1950-10-04
        </born>
        <qualification>
          extroverted beagle
        </qualification>
      </person>
      <person id="Schroeder">
        <name>
          Schroeder
        </name>
        <born>
          1951-05-30
        </born>
        <qualification>
          brought classical music to the Peanuts strip
        </qualification>
      </person>
      <person id="Lucy">
        <name>
          Lucy
        </name>
        <born>
          1952-03-03
        </born>
        <qualification>
          bossy, crabby and selfish
        </qualification>
      </person>
    </characters>
  </book>
</library>

If we want to avoid confusion while writing a schema for this instance document, we can define prefixes in the schema for both our target namespace and for the W3C XML Schema namespace, leading to a schema such as:

<?xml version="1.0"?> 
<xs:schema targetNamespace="http://dyomedea.com/ns/library"
  elementFormDefault="qualified" attributeFormDefault="unqualified"
  xmlns:lib="http://dyomedea.com/ns/library"
  xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="library">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="book" type="lib:bookType"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="person">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="name" type="xs:string"/>
        <xs:element name="born" type="xs:date"/>
        <xs:element name="dead" type="xs:date" minOccurs="0"/> 
        <xs:element name="qualification" type="xs:string"
          minOccurs="0"/>
      </xs:sequence>
      <xs:attribute name="id" type="xs:ID" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="bookType">
    <xs:sequence>
      <xs:element name="isbn" type="xs:NMTOKEN"/>
      <xs:element name="title" type="xs:string"/>
      <xs:element name="authors">
        <xs:complexType>
          <xs:sequence>
            <xs:element ref="lib:person" maxOccurs="unbounded"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="characters">
        <xs:complexType>
          <xs:sequence>
            <xs:element ref="lib:person" maxOccurs="unbounded"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
    <xs:attribute name="id" type="xs:ID" use="required"/>
    <xs:attribute name="available" type="xs:string" use="required"/>
  </xs:complexType>
</xs:schema>

In this example, the names of components defined by the schema are always unprefixed when they are defined. Because this schema only defines components in the single http://dyomedea.com/ns/library namespace (identified as the targetNamespace attribute of the xs:schema element), there isn’t any risk of confusion. The only other namespaces used here are the namespace for W3C XML Schema itself, identified with an xs prefix, and another mapping for the http://dyomedea.com/ns/library namespace, using lib as the prefix. The lib-prefixed form is used for cross-references between declarations.

A strictly equivalent schema, defining the exact same data model, can be defined using the target namespace as the default namespace of the schema document:

<?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="http://dyomedea.com/ns/library">
  <xs:element name="library">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="book" type="bookType"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="person">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="name" type="xs:string"/>
        <xs:element name="born" type="xs:date"/>
        <xs:element name="dead" type="xs:date" minOccurs="0"/> 
        <xs:element name="qualification" type="xs:string"
          minOccurs="0"/>
      </xs:sequence>
      <xs:attribute name="id" type="xs:ID" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="bookType">
    <xs:sequence>
      <xs:element name="isbn" type="xs:NMTOKEN"/>
      <xs:element name="title" type="xs:string"/>
      <xs:element name="authors">
        <xs:complexType>
          <xs:sequence>
            <xs:element ref="person" maxOccurs="unbounded"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element name="characters">
        <xs:complexType>
          <xs:sequence>
            <xs:element ref="person" maxOccurs="unbounded"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
    <xs:attribute name="id" type="xs:ID" use="required"/>
    <xs:attribute name="available" type="xs:string" use="required"/>
  </xs:complexType>
</xs:schema>

In this version, all references to W3C XML Schema’s own elements are still made using the xs prefix. Names of components are still unprefixed, but the lib prefix is now unnecessary, so all of those prefixes can disappear. Because the default namespace is defined in this document, W3C XML Schema will understand the connection between the components it defines and references to those components.

If you prefer to use prefixes on the components you are defining and use the W3C XML Schema vocabulary without prefixes, you can also define the W3C XML Namespace as the default namespace and declare a prefixed namespace (here, lib) for the components you’re defining:

<?xml version="1.0"?> 
<schema targetNamespace="http://dyomedea.com/ns/library"
  elementFormDefault="qualified" attributeFormDefault="unqualified"
  xmlns="http://www.w3.org/2001/XMLSchema"
  xmlns:lib="http://dyomedea.com/ns/library">
  <element name="library">
    <complexType>
      <sequence>
        <element name="book" type="lib:bookType"/>
      </sequence>
    </complexType>
  </element>
  <element name="person">
    <complexType>
      <sequence>
        <element name="name" type="string"/>
        <element name="born" type="date"/>
        <element name="dead" type="date" minOccurs="0"/>
        <element name="qualification" type="string" minOccurs="0"/>
      </sequence>
      <attribute name="id" type="ID" use="required"/>
    </complexType>
  </element>
  <complexType name="bookType">
    <sequence>
      <element name="isbn" type="NMTOKEN"/>
      <element name="title" type="string"/>
      <element name="authors">
        <complexType>
          <sequence>
            <element ref="lib:person" maxOccurs="unbounded"/>
          </sequence>
        </complexType>
      </element>
      <element name="characters">
        <complexType>
          <sequence>
            <element ref="lib:person" maxOccurs="unbounded"/>
          </sequence>
        </complexType>
      </element>
    </sequence>
    <attribute name="id" type="ID" use="required"/>
    <attribute name="available" type="string" use="required"/>
  </complexType>
</schema>

The references to W3C XML Schema data types are now done without a prefix while the references to components defined in the target namespace are done with a “lib” prefix.

Disruptive Attributes

So far we have seen that W3C XML Schema treats global attributes and elements alike, requiring both types to be explicitly namespace-qualified to be global. Although this approach makes sense—there’s little reason to treat elements and attributes differently—it’s different from the approach the Namespaces in XML Recommendation took. Global attributes turn out to be a rather unusual, though useful, case.

To understand this phenomenon, we need to examine the Namespaces in XML Recommendation closely. This differentiates qualified and unqualified attributes, explaining that only attributes applied to elements from another namespace need to be qualified (these are also called global attributes), and that unqualified attributes are considered to belong to the vocabulary from their parent element without needing to belong to their namespace. In this case, they inherit the membership to the namespace of their parent element without needing to show it. This is tightly linked to the fact that default namespaces do not apply to attributes (they don’t need to since attributes are considered members of the namespace of their parent without needing default namespaces). In practice, most XML vocabularies will use unqualified attributes, such as:

<book id="b0836217462" xmlns="http://dyomedea.com/ns/library"/>

or:

<lib:book id="b0836217462"
  xmlns:lib="http://dyomedea.com/ns/library"/>

Very few would use qualified attributes, such as:

<lib:book lib:id="b0836217462"
  xmlns:lib="http://dyomedea.com/ns/library"/>

Also, very few would use that or its equivalent if we use a default namespace for the element that doesn’t apply to the attribute:

<book lib:id="b0836217462" xmlns="http://dyomedea.com/ns/library"
  xmlns:lib="http://dyomedea.com/ns/library"/>

Unfortunately, since the W3C XML Schema requires that all the global attributes be qualified, this means that global attributes can’t be used for those unqualified attributes that are used most of the time in XML vocabularies, and that our unqualified id attribute cannot be declared as global. In practice, this means that most of the time we will just define local attributes within the element or complex type definitions. When we want to define unqualified attributes that may be reused in different elements, we will either define them in a specific schema without a target namespace, which will be imported (but there is risk of collision if we mix several schemas for different target namespaces following this policy), or “hide” those attributes inside of attribute groups, such as:

<xs:attributeGroup name="id">
  <xs:attribute name="id" form="unqualified" type="xs:ID"/>
</xs:attributeGroup>

Namespaces and XPath Expressions

It’s time to remember that default namespaces do not apply to XPath expressions, and that a prefix needs to be defined for each namespace used in the XPath expressions of the xs:unique, xs:key , and xs:keyref declarations!

A prefix declaration is therefore required to write expressions that reference qualified elements and attributes, even if the target namespace is defined as the default namespace. It’s also important to notice that the xs:keyref refer attribute is a QName that needs to be prefixed, and a xs:key / xs:keyref on the authors in (in our previous example) with a namespace could become:

<xs:schema targetNamespace="http://dyomedea.com/ns/library"
  elementFormDefault="qualified" attributeFormDefault="unqualified"
  xmlns:lib="http://dyomedea.com/ns/library"
  xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="library">
    <xs:complexType>
      <xs:sequence> 
        <xs:element name="book" type="lib:bookType"
          maxOccurs="unbounded"/> 
        <xs:element name="author" type="lib:authorType"
          maxOccurs="unbounded"/> 
        <xs:element name="characters" type="lib:characterType"
          maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
    <xs:key name="author">
      <xs:selector xpath="lib:author"/>
      <xs:field xpath="@id"/>
    </xs:key>
    <xs:keyref name="keyref" refer="lib:author">
      <xs:selector xpath="lib:book/lib:author-ref"/>
      <xs:field xpath="@ref"/>
    </xs:keyref>
  </xs:element>
</xs:schema>

Referencing Other Namespaces

One of the goals of the namespaces specification is to allow the use of documents mixing elements and attributes from different vocabularies. W3C XML Schema lets you take full advantage of this possibility.

Part of the library vocabulary describes persons. This could be reused by other applications, and we might want to define a specific namespace and give it the URI reference "http://dyomedea.com/ns/people":

<?xml version="1.0"?> 
<library xmlns:ppl="http://dyomedea.com/ns/people"
  xmlns="http://dyomedea.com/ns/library">
  <book id="b0836217462" available="yes">
    <isbn>
      0836217462
    </isbn>
    <title>
      Being a Dog Is a Full-Time Job
    </title>
    <authors>
      <ppl:person id="CMS">
        <ppl:name>
          Charles M Schulz
        </ppl:name>
        <ppl:born>
          1922-11-26
        </ppl:born>
        <ppl:dead>
          2000-02-12
        </ppl:dead>
      </ppl:person>
    </authors>
    <characters>
      <ppl:person id="PP">
        <ppl:name>
          Peppermint Patty
        </ppl:name>
        <ppl:born>
          1966-08-22
        </ppl:born>
        <ppl:qualification>
          bold, brash and tomboyish
        </ppl:qualification>
      </ppl:person>
      <ppl:person id="Snoopy">
        <ppl:name>
          Snoopy
        </ppl:name>
        <ppl:born>
          1950-10-04
        </ppl:born>
        <ppl:qualification>
          extroverted beagle
        </ppl:qualification>
      </ppl:person>
      <ppl:person id="Schroeder">
        <ppl:name>
          Schroeder
        </ppl:name>
        <ppl:born>
          1951-05-30
        </ppl:born>
        <ppl:qualification>
          brought classical music to the Peanuts strip
        </ppl:qualification>
      </ppl:person>
      <ppl:person id="Lucy">
        <ppl:name>
          Lucy
        </ppl:name>
        <ppl:born>
          1952-03-03
        </ppl:born>
        <ppl:qualification>
          bossy, crabby and selfish
        </ppl:qualification>
      </ppl:person>
    </characters>
  </book>
</library>

To handle these two namespaces, we need to define two different schemas (one per namespace). One will describe our vocabulary about persons as well as include the definitions of the element person and its child elements:

<?xml version="1.0"?> 
<xs:schema targetNamespace="http://dyomedea.com/ns/people"
  elementFormDefault="qualified" attributeFormDefault="unqualified"
  xmlns:ppl="http://dyomedea.com/ns/people"
  xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="person">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="name" type="xs:string"/>
        <xs:element name="born" type="xs:date"/>
        <xs:element name="dead" type="xs:date" minOccurs="0"/> 
        <xs:element name="qualification" type="xs:string"
          minOccurs="0"/>
      </xs:sequence>
      <xs:attribute name="id" type="xs:ID" use="required"/>
    </xs:complexType>
  </xs:element>
</xs:schema>

This schema describes the namespace "http://dyomedea.com/ns/people", and this vocabulary doesn’t include anything from any other namespace. The schema is then similar to the examples we’ve seen in this chapter so far. It can be used alone with documents that use only this namespace, but can also be “imported” by schemas that describe other namespaces but would like to use some of its definitions.

To do this, the schema that describes the including vocabulary needs two pieces of information. It must have a prefix for the namespaces that will be included; this is done by a usual namespace declaration. It also must have a hint on where it can find the schema for this namespace; this is done using a xs:import element:

<xs:import namespace="http://dyomedea.com/ns/people"
  schemaLocation="simple-2-ns-ppl.xsd"/>

The schema now has all the information it needs to resolve references to schema components that belong to the http://dyomedea.com/ns/people namespace. References can be made just using its prefix:

<xs:element ref="ppl:person"/>

A full schema for the library vocabulary can then be:

<?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="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="isbn" type="xs:NMTOKEN"/>
      <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:element name="characters">
        <xs:complexType>
          <xs:sequence>
            <xs:element ref="ppl:person" maxOccurs="unbounded"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
    <xs:attribute name="id" type="xs:ID" use="required"/>
    <xs:attribute name="available" type="xs:string" use="required"/>
  </xs:complexType>
</xs:schema>

Tip

When importing schemas from other namespaces, we can only refer to the global components defined in the imported schemas.

Schemas for XML, XML Base and XLink

XML Base, XLink, and XML 1.0 all define vocabularies that are composed only of attributes. Attributes such as xml:base, xlink:href, or xml:lang are designed to work with elements from any vocabulary, imparting their meaning to those elements and sometimes the descendants of those elements.

XML Attributes

In this section, we will discuss how to allow the use of a XML attribute in our document. To illustrate this, let’s use a xml:lang attribute to qualify the language of several descriptions in several languages for our book:

<?xml version="1.0"?>
<library xmlns="http://dyomedea.com/ns/library">
  <book id="b0836217462">
    <title>
      Being a Dog Is a Full-Time Job
    </title>
    <description xml:lang="en">
      Its title says it all !
    </description>
    <description xml:lang="fr">
      Son titre le résume parfaitement !
    </description>
  </book>
</library>

Following Namespaces in XML 1.0, W3C XML Schema considers xml:lang, xml:space (from the XML 1.0 recommendation) and xml:base (from the XML Base specification) to belong to the XML 1.0 namespace identified by the URI reference "http://www.w3.org/XML/1998/namespace".

Tip

The XML 1.0 namespace is an exception in the namespaces world, since we don’t need to declare it in the instance documents. Its prefix “xml” is reserved for this usage and has a special meaning, even for the parsers that do not support the namespaces. In theory, any other prefix can be assigned to the XML 1.0 namespace, but this practice is confusing and shouldn’t be encouraged.

To use attributes from this namespace, we will declare the XML namespace, import a schema, and reference both of them, as we’ve done previously for the elements from our “people” namespace:

<?xml version="1.0"?> 
<xs:schema targetNamespace="http://dyomedea.com/ns/library"
  elementFormDefault="qualified" attributeFormDefault="unqualified"
  xmlns:lib="http://dyomedea.com/ns/library"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
  <xs:import namespace="http://www.w3.org/XML/1998/namespace"
    schemaLocation="xml.xsd"/>
  <xs:element name="description">
    <xs:complexType>
      <xs:simpleContent>
        <xs:restriction base="xs:string">
          <xs:attribute ref="xml:lang"/>
        </xs:restriction>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>
  <xs:element name="library">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="lib:book"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="book">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="title" type="xs:string"/>
        <xs:element ref="lib:description" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="id" type="xs:ID" use="required"/>
    </xs:complexType>
  </xs:element>
</xs:schema>

In this example, we import a local schema (xml.xsd) for the XML namespace. The W3C has defined its own schema for the xml:lang, xml:space, and xml:base attributes. This is available at http://www.w3.org/2001/xml.xsd:

<?xml version='1.0'?>
<!DOCTYPE xs:schema PUBLIC "-//W3C//DTD XMLSCHEMA 200102//EN" "XMLSchema.dtd" >
<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace" xmlns:xs="http://
www.w3.org/2001/XMLSchema" xml:lang="en">

 <xs:annotation>
  <xs:documentation>
   See http://www.w3.org/XML/1998/namespace.html and
   http://www.w3.org/TR/REC-xml for information about this namespace.
  </xs:documentation>
 </xs:annotation>

 <xs:annotation>
  <xs:documentation>This schema defines attributes and an attribute group
        suitable for use by
        schemas wishing to allow xml:base, xml:lang or xml:space attributes
        on elements they define.

        To enable this, such a schema must import this schema
        for the XML namespace, e.g. as follows:
        &lt;schema . . .>
         . . .
         &lt;import namespace="http://www.w3.org/XML/1998/namespace"
                    schemaLocation="http://www.w3.org/2001/03/xml.xsd"/>

        Subsequently, qualified reference to any of the attributes
        or the group defined below will have the desired effect, e.g.

        &lt;type . . .>
         . . .
         &lt;attributeGroup ref="xml:specialAttrs"/>
 
         will define a type which will schema-validate an instance
         element with any of those attributes</xs:documentation>
 </xs:annotation>

 <xs:annotation>
  <xs:documentation>In keeping with the XML Schema WG's standard versioning
   policy, this schema document will persist at
   http://www.w3.org/2001/03/xml.xsd.
   At the date of issue it can also be found at
   http://www.w3.org/2001/xml.xsd.
   The schema document at that URI may however change in the future,
   in order to remain compatible with the latest version of XML Schema
   itself.  In other words, if the XML Schema namespace changes, the version
   of this document at
   http://www.w3.org/2001/xml.xsd will change
   accordingly; the version at
   http://www.w3.org/2001/03/xml.xsd will not change.
  </xs:documentation>
 </xs:annotation>

 <xs:attribute name="lang" type="xs:language">
  <xs:annotation>
   <xs:documentation>In due course, we should install the relevant ISO 2- and 3-letter
         codes as the enumerated possible values . . .</xs:documentation>
  </xs:annotation>
 </xs:attribute>

 <xs:attribute name="space" default="preserve">
  <xs:simpleType>
   <xs:restriction base="xs:NCName">
    <xs:enumeration value="default"/>
    <xs:enumeration value="preserve"/>
   </xs:restriction>
  </xs:simpleType>
 </xs:attribute>

 <xs:attribute name="base" type="xs:anyURI">
  <xs:annotation>
   <xs:documentation>See http://www.w3.org/TR/xmlbase/ for
                     information about this attribute.</xs:documentation>
  </xs:annotation>
 </xs:attribute>

 <xs:attributeGroup name="specialAttrs">
  <xs:attribute ref="xml:base"/>
  <xs:attribute ref="xml:lang"/>
  <xs:attribute ref="xml:space"/>
 </xs:attributeGroup>

</xs:schema>

Tip

Among the many controversial issues surrounding the usage of URIs, the decision to use a schema at its original location (on the W3C web site) versus using a local copy is not easy. Using a schema at its original location provides a guarantee of always accessing the most recent version, but this can be a problem if the schema becomes out of sync with the applications using it. It can also impact the ability to process documents when the hosting site is unreachable and may open a possibility of malicious substitutions of schemas.

XLink Attributes

To illustrate the usage of XLink attributes, we can replace the definition of the author that is currently within the description of a book under the authors element, with a reference to an author described as a “person” in another XML document:

<?xml version="1.0"?> 
<library xmlns="http://dyomedea.com/ns/library"
  xmlns:xlink="http://www.w3.org/1999/xlink">
  <book id="b0836217462">
    <title>
      Being a Dog Is a Full-Time Job
    </title>
    <authors>
      <person xlink:href="authors.xml#CMS"/>
    </authors>
  </book>
</library>

Again, we need to define the namespace for XLink and to import a schema before referencing the XLink attributes:

<?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:xlink="http://www.w3.org/1999/xlink"
  xmlns:lib="http://dyomedea.com/ns/library"> 
  <xs:import namespace="http://www.w3.org/1999/xlink"
    schemaLocation="xlink.xsd"/>
  <xs:element name="person">
    <xs:complexType>
      <xs:attribute ref="xlink:href" use="required"/>
      <xs:attribute ref="xlink:type" fixed="simple"/>
      <xs:attribute ref="xlink:show" fixed="embed"/>
      <xs:attribute ref="xlink:actuate" fixed="onLoad"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="library">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="lib:book"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="book">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="title" type="xs:string"/>
        <xs:element ref="lib:authors"/>
      </xs:sequence>
      <xs:attribute name="id" type="xs:ID" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="authors">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="lib:person"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Tip

Following the suggestion of the XLink specification, we have defined additional XLink attributes (type, show, and actuate) as fixed values. While this is legitimate, one should note that these values are only available to the applications that use a W3C XML Schema post-schema validation infoset (PSVI).

Although the XLink specification doesn’t provide a schema, creating the parts we need is very straightforward:

<?xml version="1.0"?> 
<xs:schema targetNamespace="http://www.w3.org/1999/xlink"
  elementFormDefault="qualified" attributeFormDefault="qualified"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:xlink="http://www.w3.org/1999/xlink">
  <xs:attribute name="type">
    <xs:simpleType>
      <xs:restriction base="xs:NMTOKEN">
        <xs:enumeration value="simple"/>
        <xs:enumeration value="extended"/>
        <xs:enumeration value="locator"/>
        <xs:enumeration value="arc"/>
        <xs:enumeration value="resource"/>
        <xs:enumeration value="title"/>
      </xs:restriction>
    </xs:simpleType>
  </xs:attribute>
  <xs:attribute name="href" type="xs:anyURI"/>
  <xs:attribute name="role" type="xs:anyURI"/>
  <xs:attribute name="arcrole" type="xs:anyURI"/>
  <xs:attribute name="title" type="xs:string"/>
  <xs:attribute name="show">
    <xs:simpleType>
      <xs:restriction base="xs:NMTOKEN">
        <xs:enumeration value="new"/>
        <xs:enumeration value="replace"/>
        <xs:enumeration value="embed"/>
        <xs:enumeration value="other"/>
        <xs:enumeration value="none"/>
      </xs:restriction>
    </xs:simpleType>
  </xs:attribute>
  <xs:attribute name="label" type="xs:NMTOKEN"/>
  <xs:attribute name="actuate">
    <xs:simpleType>
      <xs:restriction base="xs:NMTOKEN">
        <xs:enumeration value="onLoad"/>
        <xs:enumeration value="onRequest"/>
        <xs:enumeration value="other"/>
        <xs:enumeration value="none"/>
      </xs:restriction>
    </xs:simpleType>
  </xs:attribute>
  <xs:attribute name="from" type="xs:NMTOKEN"/>
  <xs:attribute name="to" type="xs:NMTOKEN"/>
</xs:schema>

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.

Importing Schemas with No Namespaces

We have seen how we can reference components from other namespaces and how the elements and attributes included in these components keep their full name, namespaces, and form (in Section 10.3). However, this mechanism has a restriction: you can only reference global elements and attributes, and global elements and attributes must always be qualified.

Therefore, the only solution to importing elements and attributes with no namespace is to import a schema without any target namespace. Let’s say that we want to describe a document in which the vocabulary to describe people has no namespace:

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

The import of the schema without a namespace is done exactly as we’ve seen earlier with schemas having target namespaces, except now we omit the namespace attribute. Another point to note is that to be able to reference the components from the schema you are including, you will have to keep the default namespace (unprefixed) available:

<?xml version="1.0"?> 
<xs:schema targetNamespace="http://dyomedea.com/ns/library"
  elementFormDefault="qualified" attributeFormDefault="unqualified"
  xmlns:lib="http://dyomedea.com/ns/library"
  xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:import schemaLocation="very-simple-2-ns-ppl-nons.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="person"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
    <xs:attribute name="id" type="xs:ID" use="required"/>
  </xs:complexType>
</xs:schema>

The included schema is:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="person" type="personType"/>
  <xs:complexType name="personType">
    <xs:sequence>
      <xs:element name="name" type="xs:string"/>
    </xs:sequence>
    <xs:attribute name="id" type="xs:ID" use="required"/>
  </xs:complexType>
</xs:schema>

In this case, all the components are considered unqualified. All the other behavior, including the difference between referencing elements or attributes and using datatypes, is relevant.

We see then that to define unqualified elements and attributes in a schema with a target namespace, we have to choose between defining them locally in the schema or defining them in a separate schema without an imported target namespace.

Chameleon Design

This chapter wouldn’t be complete without a look at the impact of namespaces on the inclusion of schemas through xs:include and xs:redefine .

When we initially introduced these features, we didn’t worry about namespaces. However, these features have some important interactions with namespaces, since W3C XML Schema restricts inclusion (or redefinition) to pieces of schema with either the same target namespace or without any target namespace (schemas for other languages being “imported” rather than “included”).

When a piece of schema that has no target namespace is included in a schema with a target namespace, the included definition acquires the target namespace of the including schema and behaves exactly as if it added the same target namespace. This feature allows creation of libraries with pieces of schema that are “namespace-transparent,” and which take the namespace of the schema in which they are imported. This method is often called “chameleon,” since the included schema takes the “color” of the context in which it is included.

To illustrate this feature and see its implication, let’s look again at the example that we’ve used throughout this chapter:

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

If we want a library of schema parts that describe a person and can be included within several vocabularies, we can include a piece of schema that has no target namespace. This piece of schema would be something like the following (note that we do not define any target namespace):

<?xml version="1.0"?> 
<xs:schema elementFormDefault="qualified"
  xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="person">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="name" type="xs:string"/>
      </xs:sequence>
      <xs:attribute name="id" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
</xs:schema>

And the including schema would look similar to the following example:

<?xml version="1.0"?> 
<xs:schema targetNamespace="http://dyomedea.com/ns/library"
  elementFormDefault="qualified"
  xmlns="http://dyomedea.com/ns/library"
  xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:include schemaLocation="very-simple-1-ns-ppl.xsd"/>
  <xs:element name="library">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="book">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="title" type="xs:string"/>
              <xs:element name="authors">
                <xs:complexType>
                 <xs:sequence>
                 <xs:element ref="person"/>
                 </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
            <xs:attribute name="id" type="xs:ID"/>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

While this looks very easy and neat, we may wonder if we are really building something modular. Including a piece of schema is similar to including a C header file. While this is slightly better than a copy/paste, the level of modularity that can be achieved in this way is very restricted.

The namespace of the element person is the namespace given to our library. An application cannot guess from looking at the instance document that this element is the same as a person element that it will find in another document describing, for example, an employee.

Looking at the modified infoset and checking the datatype doesn’t help either, since the datatype will be defined as a datatype from a schema with the target namespace of our library, and won’t match other target namespaces, including the same piece of schema.

The fact that the same person element is used by different vocabularies is totally lost by the processing of the include (or redefine). Before using it, you may consider if it isn’t more useful to include information in the instance document using a separate namespace, or at least include information in the modified infoset by importing datatypes from another namespace rather than including common definitions.

Allowing Any Elements or Attributes from a Particular Namespace

We are going to see how to accommodate any element or attribute from other namespaces using our marketing extension, the http://dyomedea.com/ns/library/mkt namespace, as an example:

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

To allow any elements from the http://dyomedea.com/ns/library/mkt namespace after the author element, we use a xs:any element:

<xs:any namespace="http://dyomedea.com/ns/library/mkt"
  processContents="skip"minOccurs="0" maxOccurs="unbounded"/>

xs:anyAttribute should be used to allow attributes:

<xs:anyAttribute namespace="http://dyomedea.com/ns/library/mkt"
  processContents="skip"/>

The two new attributes shown above are namespace and processContents .

namespace specifies the namespaces of the elements or attributes that will be accepted. The value should be a list of namespaces that URIs allow a number of wildcards. The wildcards permitted within the list are ##local (a nonqualified element) and ##targetNamespace (the target namespace). Two wildcards can also be used instead of the list: ##any (any namespace) and ##other (any namespace other than the target namespace).

Tip

It is not possible to specify that the possible namespaces are all the namespaces not defined in a schema, or even all the namespaces except those in a list. This is a serious limitation for multi-namespace vocabularies that would like to restrict some of the imported namespaces while remaining open to undefined namespaces.

processContents specifies the behavior of the validator regarding the elements or attributes from the specified namespaces. The possible values are “skip” (no validation is attempted on these elements or attributes), “strict” (schemas for the namespaces that will be included need to be available, and validators will validate the elements and attributes against these schemas), or “lax” (validators will do their best to find a schema for the included elements and attributes, validate them when they have found one, and silently skip the validation when they haven’t). For example:

<?xml version="1.0"?> 
<xs:schema targetNamespace="http://dyomedea.com/ns/library"
  elementFormDefault="qualified"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns="http://dyomedea.com/ns/library">
  <xs:element name="library">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="book"/>
      </xs:sequence> 
      <xs:anyAttribute namespace="http://dyomedea.com/ns/library/mkt"
        processContents="skip"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="book">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="title" type="xs:string"/>
        <xs:element name="authors">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="person">
                <xs:complexType>
                 <xs:sequence>
                 <xs:element name="name" type="xs:string"/>
                 </xs:sequence> 
                 <xs:attribute name="id" type="xs:string"
                   use="required"/>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element> 
        <xs:any namespace="http://dyomedea.com/ns/library/mkt"
          processContents="skip"minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="id" use="required">
        <xs:simpleType>
          <xs:restriction base="xs:hexBinary"/>
        </xs:simpleType>
      </xs:attribute>
    </xs:complexType>
  </xs:element>
</xs:schema>

This schema has been opened to accept any element from a single namespace and can be further opened to accept any element from any namespace other than the target namespace:

<xs:anyAttribute namespace="##other" processContents="skip"/>

This mechanism is flexible enough (with the exception of the lack of support for any undefined namespaces already mentioned) to accommodate a large majority of applications, but we must note that these wildcards are considered particles and can’t replace global element definitions. The unfortunate consequence is that document elements cannot be wildcarded because a schema needs to provide a closed list of possible document elements.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.98.13