MENU
The class was small and we had wonderful access to the trainer, with a lot of individual attention. The instructor...More Testimonials »

Namespaces

This tutorial was written by Nat Dunn.

Lesson Goals

  • The purpose of namespaces.
  • To declare target namespaces.
  • To set a default namespace.
  • To qualify namespaces for differentiation.

Overview

Namespaces are used to group elements and attributes that relate to each other in some special way. Namespaces are held in a unique URI (Uniform Resource Identifier). Note that, although it is possible that an XML schema is kept at this URI, it is not required. This can be a bit confusing. It is important to understand that a namespace is a set of rules that can be enforced by an application in whatever way the application wishes.

As an example, modern HTML editors understand the http://www.w3.org/1999/xhtml namespace. It is unlikely that these editors ever visit the URI that holds the XHTML namespace. Instead, these applications have built-in functionality to support the namespace. The main reason a URI is used is to provide a unique variable name to hold the namespace. Namespace authors should use URIs that they own to prevent conflicts with each other.

Purpose of Namespaces

As described above, one purpose of namespaces is to provide a unique identifier for a group of element and attribute declarations.

Another purpose is to allow instance documents to be made up of a combination of such groups without having name conflicts. For example, we could hold the book schema and song schema we have worked on throughout this course in separate namespaces. Now suppose you wanted to use both schemas to create a book of songs. Both songs and books can have Title elements. This could potentially be a source of confusion as an application might not understand which Title element to apply. By specifying which namespace the Title elements come from, the confusion is removed.

Target Namespaces

A schema can be used to populate a namespace. So far, we have not created namespaces with our schemas. That is why the root elements of our XML instances all include the xsi:noNamespaceSchemaLocation attribute.

To populate a namespace with an XML schema, set the targetNamespace attribute of the xs:schema element to a URI. You must also include a xmlns attribute, so that global elements declared in the target namespace can be referenced within the schema.

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://webucator.com/Artist" xmlns="http://webucator.com/Artist">

Code Sample:

Namespaces/Demos/Artist.xsd
<?xml version="1.0"?>
<xs:schema targetNamespace="http://www.webucator.com/Artist" 
	xmlns:xs="http://www.w3.org/2001/XMLSchema" 
	xmlns="http://www.webucator.com/Artist">
	<xs:element name="Title" type="xs:string"/>
	<xs:element name="FirstName" type="xs:string"/>
	<xs:element name="LastName" type="xs:string"/>
	<xs:element name="Name">
		<xs:complexType>
			<xs:sequence>
				<xs:element ref="Title"/>
				<xs:element ref="FirstName"/>
				<xs:element ref="LastName"/>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
	<xs:element name="Artist">
		<xs:complexType>
			<xs:sequence>
				<xs:element ref="Name"/>
			</xs:sequence>
			<xs:attribute name="BirthYear" type="xs:gYear" use="required"/>
		</xs:complexType>
	</xs:element>
</xs:schema>

This schema would be invalid if the xmlns="http://www.webucator.com/Artist" attribute were removed. That's because the Name and Artist element declarations have child elements that reference elements declared in this schema. We can only reference elements that are declared globally in namespaces used in the document (as indicated by the xmlns attributes).

Instance documents of this XML schema would take the xmlns and xsi:schemaLocation attributes. Again, the xmlns attribute allows global elements declared in the specified namespace to be used in this instance. The xsi:schemaLocation attribute is used to point to the schema associated with a namespace. Its value is the namespace name and the path to the schema separated by a space.

Code Sample:

Namespaces/Demos/MichaelJackson.xml
<?xml version="1.0"?>
<Artist BirthYear="1958" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://www.webucator.com/Artist"
	xsi:schemaLocation="http://www.webucator.com/Artist Artist.xsd">
	<Name>
		<Title>Mr.</Title>
		<FirstName>Michael</FirstName>
		<LastName>Jackson</LastName>
	</Name>
</Artist>

Default Namespaces

Let's consider the Artist.xsd schema for a moment. The first thing to remember is that the XML schema document is itself an instance document. The xmlns attributes are used to indicate what namespaces are associated with this instance.

The xs:schema element looks like this:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.webucator.com/Artist" targetNamespace="http://www.webucator.com/Artist">

The xmlns:xs attribute indicates that global elements, attributes, types, and groups in the XML Schema namespace can be used in this document, but they must be qualified with the xs: prefix.

Note that you could change this prefix to bob: or jill:, though xs: and xsd: are the most commonly used for the XML Schema namespace.

The second xmlns attribute indicates that global elements, attributes, types, and groups in the Artist namespace can be used in this document without a prefix (i.e, unqualified). The Artist namespace then is the default namespace. There can only be one default namespace in an instance document.

Now let's look at the MichaelJackson.xml instance document.

<Artist BirthYear="1958" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.webucator.com/Artist" xsi:schemaLocation="http://www.webucator.com/Artist Artist.xsd">

It uses two namespaces: http://www.w3.org/2001/XMLSchema-instance, which we will discuss later, and http://www.webucator.com/Artist.

Notice that none of the elements or attributes in the document is qualified (i.e, prefixed). That is because they all belong to the Artist namespace, which is the default namespace. The sample code below shows how this same document would look without a default namespace.

Code Sample:

Namespaces/Demos/MichaelJacksonQualified.xml
<?xml version="1.0"?>
<art:Artist BirthYear="1958"
			xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
			xmlns:art="http://www.webucator.com/Artist"
			xsi:schemaLocation="http://www.webucator.com/Artist Artist.xsd">
	<art:Name>
		<art:Title>Mr.</art:Title>
		<art:FirstName>Michael</art:FirstName>
		<art:LastName>Jackson</art:LastName>
	</art:Name>
</art:Artist>

Generally, it only makes sense to use qualifiers when using more than one namespace.

Locally Declared Elements and Attributes

By default, locally declared elements and attributes in an instance document do not need to be qualified. This can be changed in the schema by including the elementFormDefault and attributeFormDefault attributes of the xs:schema element with the value of "qualified".

First, let's look at the ArtistLocal.xsd schema, which has been modified to make all elements but the Artist element locally declared.

Code Sample:

Namespaces/Demos/ArtistLocal.xsd
<?xml version="1.0"?>
<xs:schema targetNamespace="http://www.webucator.com/Artist" 
	xmlns:xs="http://www.w3.org/2001/XMLSchema" 
	xmlns="http://www.webucator.com/Artist" 
	elementFormDefault="unqualified" 
	attributeFormDefault="unqualified">
	<xs:element name="Artist">
		<xs:complexType>
			<xs:sequence>
				<xs:element name="Name">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="Title" type="xs:string"/>
							<xs:element name="FirstName" type="xs:string"/>
							<xs:element name="LastName" type="xs:string"/>
						</xs:sequence>
					</xs:complexType>
				</xs:element>
			</xs:sequence>
			<xs:attribute name="BirthYear" type="xs:gYear" use="required"/>
		</xs:complexType>
	</xs:element>
</xs:schema>

Notice that the elementFormDefault and attributeFormDefault attributes are set to "unqualified". This is the default value, so the attributes could just have well been left out.

Now let's take a look at an instance document of this schema.

Code Sample:

Namespaces/Demos/MichaelJacksonLocal.xml
<?xml version="1.0"?>
<art:Artist BirthYear="1958"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:art="http://www.webucator.com/Artist"
	xsi:schemaLocation="http://www.webucator.com/Artist ArtistLocal.xsd">
	<Name>
		<Title>Mr.</Title>
		<FirstName>Michael</FirstName>
		<LastName>Jackson</LastName>
	</Name>
</art:Artist>

When using unqualified locals, it is not valid to use a default namespace. The schema processor must know that these elements are locally declared within a specific namespace. If a default namespace were used, the schema processor would not be able to differentiate between locally declared and globally declared elements. Therefore, we use the art: prefix to qualify the Artist namespace.

Qualified Locals

If the elementFormDefault and attributeFormDefault attributes in the xs:schema element are set to "qualified" all locals must be qualified with a prefix.

Code Sample:

Namespaces/Demos/ArtistLocalQualified.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
					xmlns="http://www.webucator.com/Artist"
					targetNamespace="http://www.webucator.com/Artist"
					elementFormDefault="qualified"
					attributeFormDefault="qualified">
	<xs:element name="Artist">
		<xs:complexType>
			<xs:sequence>
				<xs:element name="Name">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="Title" type="xs:string"/>
							<xs:element name="FirstName" type="xs:string"/>
							<xs:element name="LastName" type="xs:string"/>
						</xs:sequence>
					</xs:complexType>
				</xs:element>
			</xs:sequence>
			<xs:attribute name="BirthYear" type="xs:gYear" use="required"/>
		</xs:complexType>
	</xs:element>
</xs:schema>

Code Sample:

Namespaces/Demos/MichaelJacksonLocalQualified.xml
<?xml version="1.0"?>
<art:Artist art:BirthYear="1958"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:art="http://www.webucator.com/Artist"
	xsi:schemaLocation=
		"http://www.webucator.com/Artist ArtistLocalQualified.xsd">
	<art:Name>
		<art:Title>Mr.</art:Title>
		<art:FirstName>Michael</art:FirstName>
		<art:LastName>Jackson</art:LastName>
	</art:Name>
</art:Artist>

The result of qualifying all locals is that instance authors do not have to differentiate between local and global declarations. They simply prefix all elements and attributes with a qualifier. This has two major advantages over using unqualified locals.

  • Clarity - it is easy to tell which namespace each element belongs to.
  • Flexibility - the schema author can mix global and local declarations without worrying that the instance author will get confused. As both local and global declarations require prefixes, the instance author doesn't need to know how an element or attribute is declared.

The XMLSchema-instance Namespace

The XMLSchema-instance namespace contains only four attributes. Here is a simplified version of the schema.

Code Sample:

Namespaces/Demos/XMLSchema-instance.xsd
<?xml version='1.0'?>
<xs:schema targetNamespace="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <xs:attribute name="nil"/>
 <xs:attribute name="type"/>
 <xs:attribute name="schemaLocation"/>
 <xs:attribute name="noNamespaceSchemaLocation"/>
</xs:schema>

By specifying that an XML document uses the XMLSchema-instance namespace, the instance author gets access to the four attributes declared above. We have already seen three of these attributes used.

  • xsi:nil is used to specify that an element has no value. It is covered in Nil Values.
  • xsi:schemaLocation is used to specify the location of a schema for a particular namespace.
  • xsi:noNamespaceSchemaLocation is used to specify the location of a schema when no namespace is used.
  • xsi:type is infrequently used to specify that the element in the instance is of a different type than the one declared in the schema for that element.

Using Multiple Namespaces

Often it makes sense to use multiple namespaces for a single instance document. As an example, take a look at the following document.

Code Sample:

Namespaces/Demos/TheGirlIsMine.xml
<?xml version="1.0"?>
<Song	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
			xmlns="http://www.webucator.com/Song"
			xmlns:art="http://www.webucator.com/Artist"
			xsi:schemaLocation="http://www.webucator.com/Song Song.xsd">
	<Title>The Girl Is Mine</Title>
	<Year>1983</Year>
	<Artists>
		<art:Artist BirthYear="1958">
			<art:Name>
				<art:Title>Mr.</art:Title>
				<art:FirstName>Michael</art:FirstName>
				<art:LastName>Jackson</art:LastName>
			</art:Name>
		</art:Artist>
		<art:Artist BirthYear="1942">
			<art:Name>
				<art:Title>Mr.</art:Title>
				<art:FirstName>Paul</art:FirstName>
				<art:LastName>McCartney</art:LastName>
			</art:Name>
		</art:Artist>
	</Artists>
</Song>

The default namespace is the Song namespace. The Artist namespace is qualified with the art: prefix. Locally declared elements (there are none) and attributes (e.g, BirthYear) are unqualified.

Let's look at Song.xsd.

Code Sample:

Namespaces/Demos/Song.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
					xmlns:art="http://www.webucator.com/Artist"
					xmlns="http://www.webucator.com/Song"
					targetNamespace="http://www.webucator.com/Song">
	<xs:import namespace="http://www.webucator.com/Artist" 
		schemaLocation="Artist.xsd"/>
	<xs:element name="Title" type="xs:string"/>
	<xs:element name="Year" type="xs:gYear"/>
	<xs:element name="Artists">
		<xs:complexType>
			<xs:sequence>
				<xs:element ref="art:Artist" maxOccurs="unbounded"/>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
	<xs:element name="Song">
		<xs:complexType>
			<xs:sequence>
				<xs:element ref="Title"/>
				<xs:element ref="Year"/>
				<xs:element ref="Artists"/>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
</xs:schema>

By importing the Artist namespace with xs:import and specifying that elements in that namespace can be referenced with the xmlns:art attribute of xs:schema, elements and attributes in the Artist namespace are accessible to this schema.

Tying It All Together: XML Schema → ← Annotating XML Schemas

Client Success
  1. Compare Us
  2. Client List
  3. Testimonials
Join The Team
  1. Learn how you can become a Webucator Trainer
  2. Career Opportunities
Locations
© Webucator, Inc. All rights reserved. |Toll Free: 1-877-932-8228Toll Free: 1-877-932-8228 |Outside the USA: 315-849-2724|Fax: 315-849-2723