A Gentle Introduction to Namespaces

By Sam Ruby, September 9, 2002

This document provides an introduction to XML Namespaces..  Only a basic knowledge of XML is required.

Preface:  #

Let's start our journey by taking a look at the humble <docs> element defined in Userland's RSS 0.91 thus:

A URL, points to the documentation for the format used in the RSS file.

Several questions come to mind.  What happens if not all elements of your document are defined by that document?  Suppose you include other elements from other places?  Suppose some of those elements are named the same, but mean different things?  For example, take a look at the definition of the <docs> element in Netscape's RSS 0.91:

This tag should contain a URL that references a description of the channel.

How would you go about including both in your RSS feed?  In other words, what if you want both a link to a description of the channel itself, and to a description of the format used in the RSS file to describe the channel?

Finally, if your document contains a pointer to the documentation for the format, do you also need a version attribute on the channel?  In fact, if you include elements from multiple sources, can a single version number capture all you need to know about each?

The long form  #

Given the situation above, the first and most obvious step would be to have a docs element for each element.  However, instead of a full element, wouldn't a simple attribute do?  Voilà, you've just discovered the xmlns attribute.

Including this attribute on every element would increase the size of the document somewhat, but we will cover shortcuts later.  For now, lets discuss what sort of document should an xmlns attribute "point" to.  If you look at the W3C recommendation on namespaces, you will see that an xmlns isn't a URL after all, but a URI.  What's the difference?  Well, URI basically is geekspeak for "doesn't have to point to anything at all".  But despite the freedom the W3C recommendation gives you, a namespace should point to a document which provides more information about the element.

What sort of document?  Well that truly is completely up to you.  The SOAP guys point to XML Schemas for their envelope namespace.  The RDF guys point to an RDF schema.  You can point to a picture of your cat if somehow you feel that provides a crucial insight into the inner meaning of the element in question.  In general, some simple prose will do.

Short cuts  #

To reduce some of the keystrokes necessary to produce a document, two shortcuts are provided.  Both are rather simple, and effective.  The first is to observe that elements tend to come in packs.  So instead of defining the same namespace over and over in your document, there is a simple rule: if a given element doesn't have a namespace defined on it, use the one from it's parent.  In the simplest case, one xmlns attribute at the root can cover the entire document.

The second is for cases where you are dealing with multiple namespaces.  Instead of typing out the full xmlns attribute on each element, you declare a simple alias like this xmlns:alias="namespace".  An example of this would be xmlns:dc=" http://purl.org/dc/elements/1.1/".  You can then reference the namespace by sneaking the alias before the element name, separated by a colon.  An example would be <dc:date>2002-09-09T10:00:00-04:00</dc:date>.  The alias definition can appear on the same element, but that wouldn't save many keystrokes, would it?  It may also appear on any parent element.  The same alias name can be used in multiple places within a document, and may reference different namespaces.  The nearest parent wins.  This is useful when you cut and paste together an XML document from multiple sources.

Conclusions  #

Namespaces address the needs of documents which are defined for and used by multiple software modules.  It allows you to resolve ambiguity and avoid "collisions".  It can also be used to version at a finer granularity than at the entire document level.  Coping with Change explores this concept in the context of a remote procedure call.


Valid XHTML 1.1!