Understanding namespaces is essential to understanding XML Schema. This chapter introduces namespaces and explains their relationship to schemas.
Before we delve into the use of namespaces in schema documents, let’s take a minute to learn about namespaces in general. Namespaces are a surprisingly simple concept considering how much confusion and controversy it causes. The purpose of namespaces is to provide containers for the names used in XML. A name, such as table
, can have several meanings. Its meaning in XHTML is very different from its meaning in a hypothetical language for describing office furniture, FurnitureML. An element or attribute name in an instance can be declared to be in a namespace, which provides context and identifies the XML vocabulary to which the element or attribute belongs.
Namespaces are defined by a separate W3C recommendation called Namespaces in XML, which is in two versions: 1.0 and 1.1. XML Schema 1.0 uses Namespaces 1.0, and XML Schema 1.1 uses Namespaces 1.1. There are few substantive differences between them, mentioned in the appropriate sections of this chapter.
Namespace names are Uniform Resource Identifiers (URIs). URIs encompass URLs of various schemes (e.g., HTTP, FTP, gopher, telnet), as well as URNs (Uniform Resource Names). Many namespaces are written in the form of HTTP URLs, such as http://datypic.com/prod. It is also legal to use a URN, such as urn:example:org
.
The main purpose of a namespace is not to point to a location where a resource resides. Instead, much like a Java package name, it is intended to provide a unique name that can be associated with a particular person or organization. Therefore, namespace names are not required to be dereferenceable. That is, there does not necessarily need to be an HTML page or other resource that can be accessed at http://datypic.com/prod. The namespace URI could point to a schema, an HTML page, a directory of resources, or nothing at all. This is explained further in Section 21.8.5 on p. 589.
Namespace names are case-sensitive. Two namespaces are considered different if their capitalization is different, even if you might consider them equivalent URLs. For example, http://DATYPIC.COM/prod
and http://datypic.com/prod
represent different namespaces, because they are capitalized differently.
Although relative URI references, such as ../prod
or just plain prod
are legal as URIs, they are not appropriate namespace names. A namespace name should be unique, and it is difficult to ensure the uniqueness of ../prod
. In fact, version 1.1 of the Namespaces recommendation says that they are deprecated.
The URI syntax only allows basic Latin letters and digits, with a few special punctuation characters. Non-Latin characters can be represented, but they must be escaped. In Namespaces 1.1, and therefore when using XML Schema 1.1, namespace names are actually IRIs (Internationalized Resource Identifiers) rather than URIs, which means that non-Latin characters can be directly represented in namespace names.
An instance may include one or more namespace declarations that relate elements and attributes to namespaces. This happens through a prefix, which serves as a proxy for the namespace.
A namespace is declared using a special attribute whose name starts with the letters xmlns
. Example 3–1 shows an instance whose root element has a namespace declaration. This declaration maps the namespace http://datypic.com/prod to the prefix prod
. All of the element names in the document, namely product
, number
, and size
, are prefixed with prod
. The system
attribute does not have a prefixed name, so it is not “in” the namespace.
<prod:product xmlns:prod="http://datypic.com/prod">
<prod:number>557</prod:number>
<prod:size system="US-DRESS">10</prod:size>
</prod:product>
Prefixes are convenient because they are generally shorter than namespace names, so they make the document more readable. A more important reason for prefixes, though, is that namespace names may contain characters that are not permitted in XML names. Prefixes are constrained by the rules for XML non-colonized names, as described in Section 3.1.4 on p. 40. There is no limit to how many characters long a prefix can be, but it is best to keep prefixes short for readability.
Although the instance author may choose prefixes arbitrarily, there are commonly used prefixes for some namespaces. For example, the xsl
prefix is usually mapped to the Extensible Stylesheet Language (XSL) namespace. It is legal to map the prefix bob
to the XSL namespace and write a stylesheet with every XSL element name prefixed with bob
. However, this is not recommended because it is confusing. For the XML Schema Namespace, the commonly used prefixes are xsd
and xs
.
You can declare more than one namespace in the same instance, as shown in Example 3–2. Two prefixes, ord
and prod
, are mapped to the namespaces http://datypic.com/ord and http://datypic.com/prod, respectively. The element names in the document are prefixed with either ord
or prod
to relate them to one of the two namespaces.
<ord:order xmlns:ord="http://datypic.com/ord"
xmlns:prod="http://datypic.com/prod">
<ord:number>123ABBCC123</ord:number>
<ord:items>
<prod:product>
<prod:number>557</prod:number>
<prod:size system="US-DRESS">10</prod:size>
</prod:product>
</ord:items>
</ord:order>
Note that number
appears twice, with two different prefixes. This illustrates the usefulness of namespaces which make it obvious whether it is a product number or an order number. In most cases, the two can be distinguished based on their context in the instance, but not always.
You do not need to declare xmlns:ord
and xmlns:prod
as attributes in the order
element declaration in your schema. In fact, it is illegal to declare them. All schema processors understand that attributes prefixed with xmlns
and the unprefixed attribute with the name xmlns
are always permitted.
An instance may also include a default namespace declaration that maps unprefixed element names to a namespace. The default namespace declaration uses the attribute xmlns
, with no colon or prefix. In Example 3–3, the start order
tag contains a default namespace declaration. This declaration relates the namespace http://datypic.com/ord to all of the unprefixed element names in the document, namely order
, number
, and items
.
<order xmlns="http://datypic.com/ord"
xmlns:prod="http://datypic.com/prod">
<number>123ABBCC123</number>
<items>
<prod:product>
<prod:number>557</prod:number>
<prod:size system="US-DRESS">10</prod:size>
</prod:product>
</items>
</order>
Note that the default namespace declaration can be combined with other namespace declarations in the same document and even in the same tag.
Default namespace declarations do not directly apply to attributes. In this case, the system
attribute, although its name is not prefixed, is not in the default namespace http://datypic.com/ord. It is not directly in any namespace at all. For further explanation of the relationship between attributes and namespaces, see Section 3.1.8 on p. 44.
In the context of namespaces, there are several different kinds of names. They include:
Qualified names, known as QNames, are names that are qualified with a namespace name. This may happen one of two ways:
1. The name contains a prefix that is mapped to a namespace. In Example 3–3, prod:product
is a prefixed, qualified name.
2. The name does not contain a prefix, but there is a default namespace declared for that element. In Example 3–3, items
is an unprefixed, qualified name. This applies only to elements; there is no such thing as an unprefixed, qualified attribute name, as you will see in Section 3.1.8 on p. 44.
Unqualified names, on the other hand, are names that are not in any namespace. For element names, this means they are unprefixed and there is no default namespace declaration. For attribute names, this means they are unprefixed, period.
Prefixed names are names that contain a namespace prefix, such as prod:product
. Prefixed names are qualified names, assuming there is a namespace declaration for that prefix in scope.
Unprefixed names are names that do not contain a prefix, such as items
. Unprefixed element names can be either qualified or unqualified, depending on whether there is a default namespace declaration.
A local name is the part of a qualified name that is not the prefix. In Example 3–3, local names include items
and product
.
Non-colonized names, known as NCNames, are simply XML names that do not contain colons. That means that they are case-sensitive, they may start with a letter or underscore (_
), and contain letters, digits, underscores (_
), dashes (-
), and periods (.
). They cannot start with the letters “XML” either in lower or uppercase. All local names and unprefixed names are NCNames. Prefixes are also NCNames, because they follow these same rules.
In the previous examples, namespace declarations appeared in the start tag of the root element. Namespace declarations, including default namespace declarations, can appear in any start tag in the document. Example 3–4 shows the previous order
example, but with the namespace declaration for the http://datypic.com/prod namespace moved down to the product
tag.
<order xmlns="http://datypic.com/ord">
<number>123ABBCC123</number>
<items>
<prod:product xmlns:prod="http://datypic.com/prod">
<prod:number>557</prod:number>
<prod:size system="US-DRESS">10</prod:size>
</prod:product>
</items>
</order>
The scope of a namespace declaration is the element in whose start tag it appears, and all of its children, grandchildren, and so on. In Example 3–4, it would be invalid to use the prod
prefix outside of the product
element and its children. In Example 3–5, the second product
element uses the prod
prefix, which is illegal because the namespace declaration is outside its scope.
Generally, it is preferable to put all your namespace declarations in the root element’s start tag. It allows you to see at a glance what namespaces a document uses, there is no confusion about their scopes, and it keeps them from cluttering the rest of the document.
<order xmlns="http://datypic.com/ord">
<number>123ABBCC123</number>
<items>
<prod:product xmlns:prod="http://datypic.com/prod">
<prod:number>557</prod:number>
<prod:size system="US-DRESS">10</prod:size>
</prod:product>
<prod:product>
<prod:number>559</prod:number>
<prod:size system="US-DRESS">10</prod:size>
</prod:product>
</items>
</order>
Namespace declarations can also be overridden. If a namespace declaration appears within the scope of another namespace declaration with the same prefix, it overrides it. Example 3–6 illustrates this. In the order
tag, the prefix prod
is mapped to http://datypic.com/prod. In number
, it is mapped to http://datypic.com/prod2. The second namespace declaration overrides the first within the scope of the number
element. This includes the number
element itself.
<order xmlns="http://datypic.com/ord"
xmlns:prod="http://datypic.com/prod">
<number>123ABBCC123</number>
<items>
<prod:product>
<prod:number xmlns:prod="http://datypic.com/prod2">
557</prod:number>
<prod:size system="US-DRESS">10</prod:size>
</prod:product>
</items>
</order>
Likewise, if a default namespace declaration appears within the scope of another default namespace declaration, it overrides it, as shown in Example 3–7. The default namespace declaration in the product
start tag overrides the one on the root element, meaning that product
and its children are in the http://datypic.com/prod namespace.
<order xmlns="http://datypic.com/ord">
<number>123ABBCC123</number>
<items>
<product xmlns="http://datypic.com/prod">
<number>557</number>
<size system="US-DRESS">10</size>
</product>
</items>
</order>
A default namespace declaration may also be the empty string (that is, xmlns=""
). This means that unprefixed element names in its scope are not in any namespace. This can be used to essentially “undeclare” the default namespace.
Example 3–8 is similar to Example 3–7 except that it uses the empty string. This means that product
and its children are in no namespace.
<order xmlns="http://datypic.com/ord">
<number>123ABBCC123</number>
<items>
<product xmlns="">
<number>557</number>
<size system="US-DRESS">10</size>
</product>
</items>
</order>
In version 1.1 (but not in 1.0), you can also undeclare a prefix by using an empty string. In Example 3–9, the namespace declaration for the ord
prefix in the product
start tag undeclares the one on the root element, meaning that the ord
prefix is undefined within the scope of product
.
<ord:order xmlns:ord="http://datypic.com/ord">
<ord:number>123ABBCC123</ord:number>
<ord:items>
<prod:product xmlns:ord="" xmlns:prod="http://datypic.com/prod">
<prod:number>557</prod:number>
<prod:size system="US-DRESS">10</prod:size>
</prod:product>
</ord:items>
</ord:order>
The relationship between attributes and namespaces is slightly simpler than the relationship between elements and namespaces. Prefixed attribute names, as you would expect, are in whichever namespace is mapped to that prefix. Attributes with prefixed names are sometimes referred to as global attributes. Unprefixed attribute names, however, are never in a namespace. This is because they are not affected by default namespace declarations.
Some people make the argument that an unprefixed attribute is (or should be) in the namespace of its parent element. While it may be indirectly associated with that namespace, it is not directly in it. For the purposes of writing schemas and using other XML technologies such as XSLT and XQuery, you should treat an unprefixed attribute as if it were in no namespace at all.
Example 3–10 shows a size
element that has two attributes: app:system
and system
. app:system
is associated with the namespace http://datypic.com/app through the app
prefix. The unprefixed system
attribute is not in any namespace at all, despite the default namespace declaration.
<product xmlns="http://datypic.com/prod"
xmlns:app="http://datypic.com/app">
<number>557</number>
<size app:system="R32" system="US-DRESS">10</size>
</product>
Although an element cannot have two attributes with the same name, this example is valid because the attribute names are in different namespaces (or rather, one is in a namespace and one is not), and they therefore are considered to have different names.
Example 3–11 is also valid, even though the default namespace and the namespace mapped to the prod
prefix are the same. This is again because the unprefixed system
attribute is not in any namespace.
<product xmlns="http://datypic.com/prod"
xmlns:prod="http://datypic.com/prod">
<number>557</number>
<size system="US-DRESS" prod:system="R32">10</size>
</product>
Example 3–12 shows an invalid duplication of attributes. The problem is not that two different prefixes are mapped to the same namespace; this is perfectly acceptable. However, it is not valid for an element to have two attributes with the same name that are in the same namespace, even if they have different prefixes.
<product xmlns:prod="http://datypic.com/prod"
xmlns:prod2="http://datypic.com/prod">
<number>557</number>
<size prod:system="US-DRESS" prod2:system="R32">10</size>
</product>
This example illustrates an important point: The prefix itself has no particular meaning. Instead, it is the namespace to which it is mapped that matters when validating and comparing names. The two qualified names prod:system
and prod2:system
are equal, even though the prefixes differ.
To summarize our discussion of namespaces, Example 3–13 provides a more complex instance that shows various combinations of namespace declarations in different scopes.
<envelope>
<order xmlns="http://datypic.com/ord"
xmlns:prod="http://datypic.com/prod">
<number>123ABBCC123</number>
<items>
<product xmlns="http://datypic.com/prod">
<number prod:id="prod557">557</number>
<name xmlns="">Short-Sleeved Linen Blouse</name>
<prod:size system="US-DRESS">10</prod:size>
<prod:color xmlns:prod="http://datypic.com/prod2"
prod:value="blue"/>
</product>
</items>
</order>
</envelope>
Table 3–1 explains which namespace each name is in, and why.
Namespaces and schemas have a many-to-many relationship.
A namespace can have names defined in any number of schemas. A namespace can exist without any schema. Some namespaces have one schema that defines its names. Other namespaces have multiple schemas. These schemas may be designed to be used together, or be completely incompatible with each other. They could present different perspectives on the same information, or be designed for different purposes such as varying levels of validation or system documentation. They could be different versions of each other. There are no rules that prevent several schemas from utilizing the same namespace, with overlapping declarations. As long as the processor does not try to validate an instance against all of them at once, this is completely legal.
A schema can declare names for any number of target namespaces. Some schemas have no target namespace at all. Other schemas are represented by composing multiple schema documents, each with its own target namespace. This is described in detail in Chapter 4.
Each schema document can declare and define components for one namespace, known as its target namespace. Every globally declared or defined component (element, attribute, type, named group, or notation) is associated with that target namespace. Example 3–14 shows a schema document that declares a target namespace of http://datypic.com/prod. Three element declarations are global, and therefore all of them are in the namespace http://datypic.com/prod. Local element declarations may or may not use the target namespace of the schema document, as described in Section 6.3 on p. 98.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://datypic.com/prod"
targetNamespace="http://datypic.com/prod">
<xs:element name="product" type="ProductType"/>
<xs:element name="number" type="xs:integer"/>
<xs:element name="size" type="SizeType"/>
<xs:complexType name="ProductType">
<xs:sequence>
<xs:element ref="number"/>
<xs:element ref="size"/>
</xs:sequence>
</xs:complexType>
<!--...-->
</xs:schema>
Adding a target namespace to a schema is not just informational; the target namespace becomes an important part of the names, and it must be reflected in the instance documents. Example 3–15 shows how the elements from the previous example could appear in an instance. Since they are associated with the http://datypic.com/prod namespace, they must be qualified in some way, either through a prefix or by a default namespace declaration.
<prod:product xmlns:prod="http://datypic.com/prod">
<prod:number>557</prod:number>
<prod:size>10</prod:size>
</prod:product>
A schema document cannot have more than one target namespace. However, you can link together schema documents that have different target namespaces, using an import
. This is described in Section 4.3.2 on p. 66.
If you do not plan to use namespaces, you are not required to specify a target namespace. In this case, omit the targetNamespace
attribute entirely.
Since schema documents are XML, namespaces also apply to them. For example, all the elements used in schemas, such as schema
, element
, and simpleType
, are in the XML Schema Namespace, whose namespace name is http://www.w3.org/2001/XMLSchema. In addition, the names of the built-in simple types are in this namespace.
The prefixes most commonly mapped to this namespace are xsd
or xs
. It is recommended that you use one of these for clarity, although you could just as easily use any other prefix. Example 3–16 shows a schema document that maps the XML Schema Namespace to xs
and prefixes all of the element names in the schema document.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="number" type="xs:integer"/>
<xs:element name="size" type="SizeType"/>
<xs:simpleType name="SizeType">
<!--...-->
</xs:simpleType>
</xs:schema>
It is interesting to note that while all the element names are prefixed, all of the attribute names are unprefixed. This is because none of the attributes in the XML Schema Namespace is declared globally. This is explained further in Section 7.4 on p. 122.
The xs
prefix is also used when referring to the built-in type integer
. This is because integer
is a simple type that is defined in the schema for schemas, whose target namespace is the XML Schema Namespace.
Mapping a prefix such as xs
to the XML Schema Namespace is one of the three options for namespace declarations in schema documents. See Section 3.3.5 on p. 52 for more information.
The XML Schema Instance Namespace is a separate namespace for the four schema-related attributes that may appear in instances. Its namespace name is http://www.w3.org/2001/XMLSchema-instance. These attributes, whose names are commonly prefixed with xsi
, are: type
, nil
, schemaLocation
, and noNamespaceSchemaLocation
. They are described in Section 5.1 on p. 79.
The XML Schema Version Control Namespace is a namespace used by six attributes that signal to processors the conditions under which they should pay attention to particular schema components. Its namespace name is http://www.w3.org/2007/XMLSchema-versioning, and it is commonly associated with the prefix vc
. Four of these attributes control the portability of implementation-defined facets and types and are covered in Section 23.5.3 on p. 642. The other two indicate versions of the XML Schema language and are described in Section 23.5.2 on p. 641.
Schema documents must contain namespace declarations of both the XML Schema Namespace and the target namespace in order to resolve the references between schema components. There are three ways to set up the namespace declarations in your schema document, each of which is described in this section.
You can map the XML Schema Namespace to a prefix such as xsd
or xs
, and make the target namespace the default namespace. Example 3–17 shows a schema document that uses this approach. This method is used throughout this book. Its advantage is that it makes it clear which components are defined by XML Schema, especially when it comes to referencing built-in types.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://datypic.com/prod"
targetNamespace="http://datypic.com/prod">
<xs:element name="number" type="xs:integer"/>
<xs:element name="size" type="SizeType"/>
<xs:simpleType name="SizeType">
<!--...-->
</xs:simpleType>
</xs:schema>
If your schema document does not have a target namespace, you must map a prefix to the XML Schema Namespace. Otherwise, you will have no way of referencing other schema components that are defined in your schema document. Example 3–18 shows a schema document that does not have a target namespace and defaults the XML Schema Namespace. This is invalid, because the declaration of size
references the type SizeType
. Since the default namespace is the XML Schema Namespace, the processor will look unsuccessfully for a definition of SizeType
in the XML Schema Namespace.
<schema xmlns="http://www.w3.org/2001/XMLSchema">
<element name="number" type="integer"/>
<element name="size" type="SizeType"/>
<simpleType name="SizeType">
<!--...-->
</simpleType>
</schema>
Another alternative is to map a prefix to the target namespace, and make the XML Schema Namespace the default namespace. Example 3–19 shows a schema document that uses this approach. The names in the declarations themselves do not need to be prefixed because they automatically become part of the target namespace. The only place the prefix is used is in references to other components. For example, the declaration of size
references the type SizeType
by its qualified name. If it did not prefix the name of the type, the processor would look unsuccessfully for a definition of SizeType
in the XML Schema Namespace.
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:prod="http://datypic.com/prod"
targetNamespace="http://datypic.com/prod">
<element name="number" type="integer"/>
<element name="size" type="prod:SizeType"/>
<simpleType name="SizeType">
<!--...-->
</simpleType>
</schema>
If you plan to use identity constraints, you may be required to map a prefix to the target namespace. See Section 17.9 on p. 439 for more information.
It is also possible to map prefixes to all the namespaces, as shown in Example 3–20. This has the advantage of clarity, particularly when your schema documents import other namespaces.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:prod="http://datypic.com/prod"
targetNamespace="http://datypic.com/prod">
<xs:element name="number" type="xs:integer"/>
<xs:element name="size" type="prod:SizeType"/>
<xs:simpleType name="SizeType">
<!--...-->
</xs:simpleType>
</xs:schema>
Note that the prefix used for the target namespace in the schema does not necessarily correspond to the prefix used in the instance document. While the schema in the previous example uses the prefix prod
for the target namespace, a valid instance document could use prod
, foo
, or any other prefix, or make that namespace the default. It is the namespace names that must match, not prefixes.