XML

Declaring and Using Namespaces

Namespaces are associated with documents by way of elements, which means that you declare a namespace for a particular element with the scope you want for the namespace. More specifically, you use a namespace declaration, which looks a lot like an attribute of the element. In many cases you want a namespace to apply to an entire document, which means you'll use the namespace declaration with the root element. A namespace declaration takes the following form:

xmlns:Prefix="NameSpace"

The xmlns attribute is what notifies an XML processor that a namespace is being declared. The NameSpace portion of the namespace declaration is where the namespace itself is identified. This portion of the declaration identifies a URI that guarantees uniqueness for elements and attributes used within the scope of the namespace declaration.

The Prefix part of the namespace declaration allows you to set a prefix that will serve as a shorthand reference for the namespace throughout the scope of the element in which the namespace is declared. The prefix of a namespace is optional and ultimately depends on whether you want to use qualified or unqualified element and attribute names throughout a document. A qualified name includes the Prefix portion of the namespace declaration and consists of two parts: the prefix and the local portion of the name. Examples of qualified names include mov:title, mov:director, and mov:rating. To use qualified names, you must provide Prefix in the namespace declaration. Following is a simple example of a qualified name:

<mov:title>Raising Arizona</mov:title>

Declaring a namespace in an XML document is a little like declaring a variable in a programming languagethe declared namespace is available for use but doesn't actually enter the picture until you specify an element with a qualified name.

In this example, the prefix is mov and the local portion of the name is title. Unqualified names don't include a prefix and are either associated with a default namespace or no namespace at all. The prefix of the namespace declaration isn't required when declaring a default namespace. Examples of unqualified names are title, director, and rating. Unqualified names in a document look no different than if you weren't using namespaces at all. The following code shows how the movie example would be coded using unqualified names:

<title>Raising Arizona</title>

Notice that in this example the <title> and </title> tags are used so that you would never know a namespace was involved. In this case, you are either assuming a default namespace is in use or that there is no namespace at all.

It's important to clarify why you would use qualified or unqualified names because the decision to use one or the other determines the manner in which you declare a namespace. There are two different approaches to declaring namespaces:

  • Default declaration The namespace is declared without a prefix; all element and attribute names within its scope are referenced using unqualified names and are assumed to be in the namespace.

  • Explicit declaration The namespace is declared with a prefix; all element and attribute names associated with the namespace must use the prefix as part of their qualified names or else they are not considered part of the namespace.

The next sections dig a little deeper into these namespace declarations.

Default Namespaces

Default namespaces represent the simpler of the two approaches to namespace declaration. A default namespace declaration is useful when you want to apply a namespace to an entire document or section of a document. When declaring a default namespace, you don't use a prefix with the xmlns attribute. Instead, elements are specified with unqualified names and are therefore assumed to be part of the default namespace. In other words, a default namespace declaration applies to all unqualified elements within the scope in which the namespace is declared. Following is an example of a default namespace declaration for a movie collection document:

<mediacollection xmlns="http://www.xyz.com/ns/movies">
  <movie type="comedy" rating="PG-13" review="5" year="1987">
    <title>Raising Arizona</title>
    <comments>A classic one-of-a-kind screwball love story.</comments>
  </movie>
  <movie type="comedy" rating="R" review="5" year="1988">
    <title>Midnight Run</title>
    <comments>The quintessential road comedy.</comments>
  </movie>
</mediacollection>

In this example, the http://www.xyz.com/ns/movies namespace is declared as the default namespace for the movie document. This means that all the unqualified elements in the document (mediacollection, movie, title, and so on) are assumed to be part of the namespace. A default namespace can also be set for any other element in a document, in which case it applies only to that element and its children. For example, you could set a namespace for one of the title elements, which would override the default namespace that is set in the mediacollection element. Following is an example of how this is done:

<mediacollection xmlns="http://www.xyz.com/ns/movies">
  <movie type="comedy" rating="PG-13" review="5" year="1987">
    <title>Raising Arizona</title>
    <comments>A classic one-of-a-kind screwball love story.</comments>
  </movie>
  <movie type="comedy" rating="R" review="5" year="1988">
    <title xmlns="http://www.xyz.com/ns/title">Midnight Run</title>
    <comments>The quintessential road comedy.</comments>
  </movie>
</mediacollection>

Notice in the title element for the second movie element that a different namespace is specified. This namespace applies only to the title element and overrides the namespace declared in the mediacollection element. Although this admittedly simple example doesn't necessarily make a good argument for why you would override a namespace, it can be a bigger issue in documents where you mix different XML languages.

Generally speaking, default namespaces work better when you're dealing with a single namespace. When you start incorporating multiple namespaces, it is better to explicitly refer to each namespace using a prefix.

Explicit Namespaces

An explicit namespace is useful whenever you want exacting control over the elements and attributes that are associated with a namespace. This is often necessary in documents that rely on multiple schemas because there is a chance of having a name clash between elements and attributes defined in the two schemas. Explicit namespace declarations require a prefix that is used to distinguish elements and attributes that belong to the namespace being declared. The prefix in an explicit declaration is used as a shorthand notation for the namespace throughout the scope in which the namespace is declared. More specifically, the prefix is paired with the local element or attribute name to form a qualified name of the form Prefix:Local. Following is the movie example with qualified element and attribute names:

<mediacollection xmlns:mov="http://www.xyz.com/ns/movies">
  <mov:movie mov:type="comedy" mov:rating="PG-13" mov:review="5" mov:year="1987">
    <mov:title>Raising Arizona</mov:title>
    <mov:comments>A classic one-of-a-kind screwball love story.</mov:comments>
  </mov:movie>
  <mov:movie mov:type="comedy" mov:rating="R" mov:review="5" mov:year="1988">
    <mov:title>Midnight Run</mov:title>
    <mov:comments>The quintessential road comedy.</mov:comments>
  </mov:movie>
</mediacollection>

The namespace in this code is explicitly declared by the shorthand name mov in the namespace declaration; this is evident in the fact that the name mov is specified after the xmlns keyword. Once the namespace is declared, you can use it with any element and attribute names that belong in the namespace, which in this case is all of them.

I mentioned earlier that one of the primary reasons for using explicit namespaces is when multiple schemas are being used in a document. In this situation, you will likely declare both namespaces explicitly and then use them appropriately to identify elements and attributes throughout the document. Listing 5.1 is an example of a media collection document that combines both movies and music information into a single format.

Listing 5.1. The Media Collection Example Document
 1: <?xml version="1.0"?>
 2:
 3: <mediacollection xmlns:mov="http://www.xyz.com/ns/movies"
 4:   xmlns:mus="http://www.xyz.com/ns/music">
 5:   <mov:movie mov:type="comedy" mov:rating="PG-13" mov:review="5"
 6:     mov:year="1987">
 7:     <mov:title>Raising Arizona</mov:title>
 8:     <mov:comments>A classic one-of-a-kind screwball love story.
 9:     </mov:comments>
10:   </mov:movie>
11:
12:   <mov:movie mov:type="comedy" mov:rating="R" mov:review="5" mov:year="1988">
13:     <mov:title>Midnight Run</mov:title>
14:     <mov:comments>The quintessential road comedy.</mov:comments>
15:   </mov:movie>
16:
17:   <mus:music mus:type="indy" mus:review="5" mus:year="1990">
18:     <mus:title>Cake</mus:title>
19:     <mus:artist>The Trash Can Sinatras</mus:artist>
20:     <mus:label>Polygram Records</mus:label>
21:     <mus:comments>Excellent acoustical instruments and extremely witty
22:       lyrics.</mus:comments>
23:   </mus:music>
24:
25:   <mus:music mus:type="rock" mus:review="5" mus:year="1991">
26:     <mus:title>Travelers and Thieves</mus:title>
27:     <mus:artist>Blues Traveler</mus:artist>
28:     <mus:label>A&amp;M Records</mus:label>
29:     <mus:comments>The best Blues Traveler recording, period.</mus:comments>
30:   </mus:music>
31: </mediacollection>

Just because attributes are considered parts of elements, they don't have to be fully qualified with a namespace prefix. As the media collection example reveals, attributes require a namespace prefix in order to be referenced as part of a namespace.

In this code, the mov and mus namespaces (lines 3 and 4) are explicitly declared in order to correctly identify the elements and attributes for each type of media. Notice that without these explicit namespaces it would be difficult for an XML processor to tell the difference between the title and comments elements because they are used in both movie and music entries.

When you actually start using XML languages that aren't of your own creation, you'll specify a namespace that doesn't involve your own URI. For example, the namespace for the SVG (Scalable Vector Graphics) markup language that you learn about in the next tutorial is http://www.w3.org/2000/svg.

Just to help hammer home the distinction between default and explicit namespace declarations, let's take a look at one more example. This time the media collection declares the movie namespace as the default namespace and then explicitly declares the music namespace using the mus prefix. The end result is that the movie elements and attributes don't require a prefix when referenced, whereas the music elements and attributes do. Check out the code in Listing 5.2 to see what I mean.

Listing 5.2. A Different Version of the Media Collection Example Document That Declares the Movie Namespace as a Default Namespace
 1: <?xml version="1.0"?>
 2:
 3: <mediacollection xmlns="http://www.xyz.com/ns/movies"
 4:   xmlns:mus="http://www.xyz.com/ns/music">
 5:   <movie type="comedy" rating="PG-13" review="5" year="1987">
 6:     <title>Raising Arizona</title>
 7:     <comments>A classic one-of-a-kind screwball love story.</comments>
 8:   </movie>
 9:
10:   <movie type="comedy" rating="R" review="5" year="1988">
11:     <title>Midnight Run</title>
12:     <comments>The quintessential road comedy.</comments>
13:   </movie>
14:
15:   <mus:music mus:type="indy" mus:review="5" mus:year="1990">
16:     <mus:title>Cake</mus:title>
17:     <mus:artist>The Trash Can Sinatras</mus:artist>
18:     <mus:label>Polygram Records</mus:label>
19:     <mus:comments>Excellent acoustical instruments and extremely witty
20:       lyrics.</mus:comments>
21:   </mus:music>
22:
23:   <mus:music mus:type="rock" mus:review="5" mus:year="1991">
24:     <mus:title>Travelers and Thieves</mus:title>
25:     <mus:artist>Blues Traveler</mus:artist>
26:     <mus:label>A&amp;M Records</mus:label>
27:     <mus:comments>The best Blues Traveler recording, period.</mus:comments>
28:   </mus:music>
29: </mediacollection>

The key to this code is the default namespace declaration, which is identified by the lone xmlns attribute (line 3); the xmlns:mus attribute explicitly declares the music namespace (line 4). When the xmlns attribute is used by itself with no associated prefix, it is declaring a default namespace, which in this case is the music namespace.