XML - NAMESPACE

BASICS  |  DOM  |  SCHEMA

   
Namespace

 

Elements, and particularly attributes, might be more conveniently used in multiple contexts. An attribute, title, might refer to a book's title. Or it might refer to a job title, or the title of a person's name (Mr., Mrs., etc). As a solution, title could be assigned a prefix, for a unique namespace, so that any processing, any XSLT transform, could differentiate between 'meanings' of the same attribute named, title.

For the same reason, there's even a more obvious use for namespaces, as well. They can be used by a transform engine, like XSLT, to identify not just elements/tokens but that these indicate particular processing commands.

 
Declarations

 

A new namespace is declared as an attribute of some element. That's just how the committee devised it. Everything under that element, inside its 'scope', can be part of that namespace if the same prefix is then used on those elements or attributes. The declaration attribute for a namespace looks like:

<element-name xmlns:prefix="uri">
 

The "xmlns:" is the specific name you must use, for this declaration attribute/'command'. The prefix is what the namespace is called. It's that prefix which you use to explicitly assign some element or attribute to that particular namespace. The XSLT engine, or processor, however, will associate the URI with the element or attribute. So the XSLT 'code' uses the prefix. And XSLT processor uses the URI. So in this case, since no prefix was used on the element, itself ("element-name", in this example), the element is not part of any declared namespace, unless a default was declared.

 
Default (non-prefix)

 

In msxml, "xml" is itself a reserved namespace, which doesn't have to be explicitly declared. It has a default uri of - http://www.w3.org/XML/1998/namespace - and provides a couple of readily available functions that you could call. However, one can explictly define a default namespace by simply declaring a uri without using any prefix. This will be the current default, or 'non-prefixed', namespace:

<element-name xmlns="uri">
 

Elements under this declaration which use no prefix, are automatically included in this non-prefix namespace. Attributes are different. Otherwise, they are associated with the element in which they are used. However, for purposes of namespaces, unless a specific namespace prefix is used with an attribute, an attribute itself is not even part of the default namespace. It has a null namespace, none. Or, more properly, it just simply has no namespace. (Using the default namespace can be dicey with XPath version 1, as explained there.)

 
URI

 

The uri, itself, might point to a validation schema. But this uri really, at this point in the development of XML, etc., can be thought of as just a meaningless string. You can put anything there. Some are predefined, built-in. You use such for XSLT, for example, or for XSD schema, so that certain elements are treated as processor commands. But, otherwise, the uri is just a made-up string. You have to put something there. Technically, it is this URI, as such, that is associated with each element and prefixed attribute.

 
Scope Example

 

Here's an example:

<names xmlns:user="namespace1">
   <subnames xmlns:user2="namespace2">
     <user2:person>Andy Taylor</user2:person>
     <occupation xmlns:user3="namespace3">sheriff</occupation>
   </subnames>
   <user:subnames episode="#204">
     <person>Gomer Pyle</person>
     <occupation>door-to-door salesmen</occupation>
   </user:subnames>
</names>

 

In addition to the reserved namespace, xml, three namespaces are explicitly declared, here - making it a total of four. There is no non-prefix, default declared, in this example (default namespaces, again, can pose problems for XPath version 1). Starting with the root node, names, the first new namespace, namespace1, is declared. Since the user prefix isn't used on the names element, that element is not part of the namespace1 namespace. That element is not part of any namespace. It would be included in a default namespace, if one had been declared. The very next sub-element, subnames, itself has a new namespace declaration, namespace2. Again, no prefix is used for the element. However, one could specify either user or user2 since both are declared in the same or superior elements and so can be 'seen' by that first subnames element. At occupation, yet another namespace is declared. Again no prefix. However, the user2 prefix is specified for the person element, just above. That element is then part of the namespace2 namespace. The user prefix is used with the second subnames, here. That puts that element in the namespace1 namespace.

So, to repeat, the first subnames, for example, could have been included in the same namespace2 namespace which was declared in its own attribute:

<user2:subnames xmlns:user2="namespace2">

 

So that subnames element is part of the namespace2 namespace. The 'scope', or whether an element can 'see' a namespace declaration, is if that namespace is declared as an attribute of that element, or declared as an attribute of a superior element. In the case of the occupation element, above, where the namespace is declared with the uri namespace3 and the user3 prefix, the allowable namespaces for that occupation element would simply be all FOUR namespaces, with the prefixes - xml, user, user1, user2. For the person node under the first subnames, the 'Andy Taylor' element, three namespaces could be allowed for that element, identified by prefix: xml, user, and user2. For 'Gomer Pyle', it would only be user and the reserved, xml, since no default namespace was declared. And so on.

 
URI Function (XPath)

 

To see if an element is actually assigned to a particular namespace, however, the built-in XPath function, namespace-uri(), is used on the element, itself. XPath and XSLT are covered, elsewhere. But this would be an example of the use of the namespace-uri() function. The "stylesheet" is the XSLT program/transform. The stuff in "match", "select" and "test" is the XPath 'query' language.

 
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <xsl:for-each select="//*">
  element: <xsl:value-of select="name()"/>&#160;&#160;
  uri: 
    <xsl:choose>
      <xsl:when test="namespace-uri()">
        <xsl:value-of select="namespace-uri()"/>
      </xsl:when>
      <xsl:otherwise>NULL</xsl:otherwise>
    </xsl:choose><br/>
  </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Which reports:

element: names, uri: NULL 
element: subnames, uri: NULL 
element: user2:person, uri: namespace2
element: occupation, uri: NULL 
element: user:subnames, uri: namespace1
element: person, uri: NULL 
element: occupation, uri: NULL 

 

Change things around, run the same XSLT transform, and you might get:

 
<user:names xmlns:user="namespace1" xmlns="namespace3">
     <subnames xmlns:user2="namespace2">
         <user2:person>Andy Taylor</user2:person>
         <occupation>sheriff</occupation>
     </subnames>
     <subnames episode="#204" xmlns="namespace4">
         <user:person>Gomer Pyle</user:person>
         <person>Boss</person>
         <user2:occupation xmlns:user2="namespace5">
             door-to-door salesmen
         </user2:occupation>
     </subnames>
</user:names>
 
element: user:names, uri: namespace1
element: subnames, uri: namespace3 (non-prefix default)
element: user2:person, uri: namespace2
element: occupation, uri: namespace3 (non-prefix default)
element: subnames, uri: namespace4 (non-prefix default)
element: user:person, uri: namespace1
element: person, uri: namespace4 (non-prefix default)
element: user2:occupation, uri: namespace5

 

You can position the cursor over the namespace declaration, above, and all elements that are included in that namespace will be highlighted. You can see that the default was re-declared from namespace3 to namespace4 down in the second subnames element. Similarly, while not 'seen' by either one, the user2 prefix is used twice, for different namespaces. The top names element is prefixed with user, so it becomes part of that namespace. The first subnames has no prefix, so is assigned to the default namespace3. And so on.


 
 More to read:

ZVON Simple examples on the use of namespaces
O'Reilly XML.com Intro to XML namespaces
W3 Schools W3schools intro to XML namespaces
Microsoft article Fairly detailed look at namespaces
Microsoft Help Microsoft's original compiled help file for msxml 4.0 (click: download de SDK)
(Robin) Cover Pages Cover's namespace links
(Robin) Cover Page archive Note on explicitly declaring all attribute namespaces
James Clark Slightly different explanation of XML namespaces
W3C XML Namespaces WWW Consortium 1999 finalized spec for namespaces