XML Namespaces Explained

Why do we need namespaces?

There are really two fundamental needs for namespaces:

  1. To disambiguate between two elements that happen to share the same name
  2. To group elements relating to a common idea together

OK, so these statements are a bit vague – let’s give some examples here:

To disambiguate between elements that happen to share the same name

Consider that:

  • In (x)html there is a table element. There is also an element of the same name in XSL-FO.
  • a, title and style are all elements in both (x)html and SVG.

So, how can you tell an SVG title from an (x)html one?

To group elements relating to a common idea together

In (x)html, the table, style and a elements are governed by specific rules about what is required, and what may and may not be included. The definitions required by these rules should all be included in the same place.

So, for example, my own XML-based data may have validating rules, and I will want to:

  • define those rules in the same place, and
  • differentiate these particular rules from any other rule-set that I (or someone else) define.
What is a Namespace?

A namespace is a unique URI (Uniform Resource Locator)

The advantage of this format is that anyone who transmits XML can be assumed to have access to a domain name (the bit after the http://, but before the next /). It’s bad form to piggy-back on someone else’s domain (especially if they don’t know you’re doing it!).

In an XML document, the URI is associated with a prefix, and this prefix is used with each element to indicate to which namespace the element belongs. For example,

rdf:description  
xsl:template  
zblsa:data

In these examples,

  • the part before the colon is the prefix
  • the part after the colon is the local part
  • any prefixed element is a qualified name
  • any un-prefixed element is an unqualified name
How do I use a Namespace?

To use a namespace, you first associate the URI with a namespace:

<foo:tag xmlns:foo="http://me.com/namespaces/foofoo">.

This defines foo as the prefix for the namespace for that element tag. The attribute prefixed with xmlns works like a command to say "link the following letters to a URI". As no well-formed document can contain two identical attributes, the part that appears after the colon stops the same prefix being defined twice simultaneously.

Defining One Prefix for a Namespace

Here’s an example where we define one prefix for a namespace:

<foo:tag xmlns:foo="http://me.com/namespaces/foofoo"> 

 <foo:head>
   <foo:title>An example document</foo:title>
 </foo:head>

 <foo:body>
   <foo:e1>a simple document</foo:e1>
   <foo:e2>
     Another element
   </foo:e2>
 </foo:body>
</foo:tag>

For all elements within <foo:tag>, the namespace prefix foo is associated with the namespace URI http://me.com/namespaces/foofoo.

Defining Multiple Prefixes for the Same Namespace

It is possible for different prefixes to actually refer to the same namespace, as follows:

<tag>  
 
 <foo:head xmlns:foo="http://me.com/namespaces/foofoo">  
   <foo:title>An example document</foo:title>  
 </foo:head>  
 
 <bar:body xmlns:bar="http://me.com/namespaces/foofoo">  
   <bar:e1>a simple document</bar:e1>  
   <bar:e2>  
     Another element  
   </bar:e2>  
 </bar:body>  
<tag>

Defining the Same Prefix for Multiple Namespaces

It is also possible (though not recommended) for the same prefix refer to different namespaces, depending on their context:

<myns:html xmlns:myns="http://www.w3c.org/1999/xhtml">  
 
<myns:head>  
<myns:title>A really bad idea</myns:title>  
</myns:head>  
 
<myns:body>  
 <myns:h1>A really bad idea</myns:h1>  
   <myns:pre>  
     <myns:pre xmlns:myns="http://my.com/namespaces/test-data">  
       <myns:table>  
         <myns:data>  
           Hello World  
         </myns:data>  
       </myns:table>  
     </myns:pre>  
  </myns:pre>  
</myns:body>

Note: This is not a good idea!

Multiple Namespaces

If you’re using namespaces, you will almost certainly need to use several namespaces at once — so how can you declare more than one namespace at a time?

What you do is use more than one xmlns declaration, like this:

<foo:tag xmlns:foo="http://me.com/namespaces/foofoo"  
        xmlns:bar="http://me.com/namespaces/foobar"  
        >  
 
 <foo:head>  
   <foo:title>An example document</foo:title>  
 </foo:head>  
 
 <bar:body>  
   <bar:e1>a simple document</bar:e1>  
   <bar:e2>  
     Another element  
   </bar:e2>  
 </bar:body>  
</foo:tag>
The Default Namespace

Question: If you use any namespaces, do all elements have to exist within a namespace?

Answer: Yes, but this doesn’t have to be a problem!

It is permissible to define a namespace that is associated with no prefix — they’re the unqualified names we touched on above.

This is of particular importance for xhtml, as one of the requirements of this language is that xhtml doesn’t break HTML — and HTML doesn’t understand prefixes!

To define the default namespace, simply allocate an xmlns with no prefix:

<xhtml xmlns="http://www.w3c.org/1999/xhtml"> 

For example:

<html xmlns="http://www.w3c.org/1999/xhtml"  
     xmlns:bar="http://me.com/namespaces/foobar"  
     >  
 
 <head>  
   <title>An example document</title>  
 </head>  
 
 <body>  
   <bar:e1>a simple document</bar:e1>  
   <bar:e2>  
     Another element  
   </bar:e2>  
 </body>  
</html>

Attributes and Namespace

For any specific element, an attribute may only exist once. This makes attributes slightly different to elements.

Attributes may be placed in a specific namespace (<.... myns:myattib="foo" ...>) or they may be left unqualified.

The normal "rule" for attributes is to place them within a namespace only if the attribute in question is defined by a particular namespace (such as xlink or rdf attributes).

Attributes that have no namespace prefix are not defined by a namespace. Note that this is not the same as being in the default namespace.

Placing attributes in namespaces only becomes important if you require your document to conform to a DTD or Schema that defines the attribute as being qualified.

What do I Put at the End of a Namespace URI?

Nothing!

Ok, so this isn’t really helpful. The problem here is that humans see a URL, so they want to point their Web browser at it to see what they get. This is a purely human thing, and is a consequence of the decision to standardise URIs for namespaces.

To quote Claude L. Bullard (from the XML-Dev email list):

The flaw is the conflation of name, location and identity, but that flaw is the basic feature by which the WWW runs, so we are stuck there. All the handwaving about URN/URI/URL doesn’t avoid the simple fact that if one puts http:// anywhere in browser display space, the system colors it blue and puts up a finger.

The monkey expects a resource and when it doesn’t get one, this shocks the monkey. Monkeys don’t read specs to find out why they shouldn’t be shocked. They turn red and put up a finger.

What many people do to avoid this "shock" factor is post a document that describes the namespace to the errant viewer. A new idea that builds on this approach, and is now emerging from XML-dev, is RDDL (the Resource Directory Description Language).

Further Reading

Main XML portals

Portals that have information on XML

Win an Annual Membership to Learnable,

SitePoint's Learning Platform

No Reader comments

Comments on this post are closed.