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.