XML Namespaces Primer

Why do we need namespaces?

Namespaces provide a way to:

What Do Namespace Names Point At?

One of the confusing things is that, by convention, namespace names are URLs. You might expect that since they are Web addresses, they must be the address of some something special. They are not. A namespace name may be a URL, but it is immaterial what they point to, it is only important that the namespace name is unique. The reason that URLs are used as namespace names is that they contain domain names (e.g. www.dataaccess.com), which are globally unique across the Internet.

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

<xsl:template>

<air:reservations>

The part before the colon is the prefix. The part after the colon is the local part. Any prefixed element is called a qualified name. Any un-prefixed element is an unqualified name.

Namespaces by Example

The XML document below contains a node, <reservations>, containing several <trip> child nodes. Imagine this data refers to airline reservations.

<reservations>

  <trip>

    <origin>Chicago</origin>

    <destination>Phoenix</destination>

    <seat>d4</seat>  

    <name>Jim Shoe</name>

    <date>06/05/05</date>

  </trip>

  <trip>

    <origin>Boston</origin>

    <destination>Miami</destination>

    <seat>c1</seat>  

    <name>Bob Sled</name>

    <date>06/05/05</date>

  </trip>

</reservations>

If this were the only XML document with reservations we needed to process then namespaces would be unnecessary. However, what if we also need to process rental car reservations as shown in the following XML document?

<reservations>

  <trip>

    <make>Chevrolet Cavalier</make>

    <origin>Chicago</origin>

    <destination>Phoenix</destination>

    <name>Jim Shoe</name>

    <date>06/06/05</date>

  </trip>

  <trip>

    <make>Dodge Caravan</make>

    <origin>Miami</origin>

    <destination>Chicago</destination>

    <name>Bob Sled</name>

    <date>06/06/05</date>

  </trip>

</reservations>

This document also contains <reservation> and <trip> tags, but the data stored in the <trip> elements differ from that in the airline reservation document. What happens if we need to combine both XML documents and process the resulting combined XML?

In this case we will need some way to distinguish air travel reservations from rental car reservations. We can do this by using prefixes as shown in the combined XML document below:

<tripPlan>

  <air:reservations>

    <air:trip>

      <air:origin>Chicago</air:origin>

      <air:destination>Phoenix</air:destination>

      <air:seat>d4</air:seat>  

      <air:name>Jim Shoe</air:name>

      <air:date>06/05/05</air:date>

    </air:trip>

    <air:trip>

      <air:origin>Boston</air:origin>

      <air:destination>Miami</air:destination>

      <air:seat>c1</air:seat>  

      <air:name>Bob Sled</air:name>

      <air:date>06/05/05</air:date>

    </air:trip>

  </air:reservations>

  <car:reservations>

    <car:trip>

      <car:make>Chevrolet Cavalier</car:make>

      <car:origin>Chicago</car:origin>

      <car:destination>Phoenix</car:destination>

      <car:name>Jim Shoe</car:name>

      <car:date>06/06/05</car:date>

    </car:trip>

    <car:trip>

      <car:make>Dodge Caravan</car:make>

      <car:origin>Miami</car:origin>

      <car:destination>Chicago</car:destination>

      <car:name>Bob Sled</car:name>

      <car:date>06/06/05</car:date>

    </car:trip>

  </car:reservations>

</tripPlan>

Prefixes have no meaning by themselves. The above example is not valid because the prefixes are not associated with namespace. A namespace and its prefix is defined with the xmlns attribute (xmlns:namespacePrefix="namespaceName").

<air:reservations xmlns:air="www.dataaccess.com/airTravel">

and,

<car:reservations xmlns:car="www.dataaccess.com/carTravel">

Note that it is the namespace name that must be unique. The namespace name often references some domain belonging to the organization that is in control of the structure of the XML data grouped under that namespace. In such a case the namespace will look like a URL but it is not. It merely uses a URL-like name to create a unique namespace. The URL does not have to exist.

Another way to combine the air and car reservations in a single XML document might be as follows:

<tp:tripPlan xmlns:air="www.dataaccess.com/airTravel"

          xmlns:car="www.dataaccess.com/carTravel"

          xmlns:tp="www.dataaccess.com/travel">

  <air:reservations>

    <air:trip>

      <air:origin>Chicago</air:origin>

      <air:destination>Phoenix</air:destination>

      <air:seat>d4</air:seat>  

      <air:name>Jim Shoe</air:name>

      <air:date>06/05/05</air:date>

    </air:trip>

    <air:trip>

      <air:origin>Boston</air:origin>

      <air:destination>Miami</air:destination>

      <air:seat>c1</air:seat>  

      <air:name>Bob Sled</air:name>

      <air:date>06/05/05</air:date>

    </air:trip>

  </air:reservations>

  <car:reservations>

    <car:trip>

      <car:make>Chevrolet Cavalier</car:make>

      <car:origin>Chicago</car:origin>

      <car:destination>Phoenix</car:destination>

      <car:name>Jim Shoe</car:name>

      <car:date>06/06/05</car:date>

    </car:trip>

    <car:trip>

      <car:make>Dodge Caravan</car:make>

      <car:origin>Miami</car:origin>

      <car:destination>Chicago</car:destination>

      <car:name>Bob Sled</car:name>

      <car:date>06/06/05</car:date>

    </car:trip>

  </car:reservations>

</tp:tripPlan>

In this document we can still distinguish between air and car reservations because each <reservations> element has a prefix that points to a different namespace. In this example we also created yet another namespace and prefix for the entire <tripPlan> document.

Default Namespace

Defining a default namespace for an element means we don't have to use prefixes in the child elements. A default namespace definition has the following syntax:

xmlns="namespace"

For example:

<chair xmlns="http://www.dataaccess.com/furniture/chairs">

  <name>Art Deco Chrome Frame</name>

  <price>190</price>

<chair>

In this example the <chair>, <name> and <price> elements all belong to the defined namespace without the need to use a prefix.

The following <tripPlan> document is identical to the earlier example.

<tripPlan xmlns="www.dataaccess.com/travel">

  <reservations xmlns="www.dataaccess.com/airTravel">

    <trip>

      <origin>Chicago</origin>

      <destination>Phoenix</destination>

      <seat>d4</seat>  

      <name>Jim Shoe</name>

      <date>06/05/05</date>

    </trip>

    <trip>

      <origin>Boston</origin>

      <destination>Miami</destination>

      <seat>c1</seat>  

      <name>Bob Sled</name>

      <date>06/05/05</date>

    </trip>

  </reservations>

  <reservations xmlns="www.dataaccess.com/carTravel">

    <trip>

      <make>Chevrolet Cavalier</make>

      <origin>Chicago</origin>

      <destination>Phoenix</destination>

      <name>Jim Shoe</name>

      <date>06/06/05</date>

    </trip>

    <trip>

      <make>Dodge Caravan</make>

      <origin>Miami</origin>

      <destination>Chicago</destination>

      <name>Bob Sled</name>

      <date>06/06/05</date>

    </trip>

  </reservations>

</tripPlan>

The default namespace only applies to document elements. Attributes either belong to a specific namespace (as defined by a prefix before the attribute name) or, if there is no prefix, they belong to the global namespace (see below).

Global Namespace

When an XML document does not define any namespace (using the xmlns attribute) then each element and attribute of that document can be said to belong to the global namespace, i.e. the namespace shared by all elements and attributes of all XML documents where namespaces are not defined.

Processing XML Documents with Namespaces in DataFlex

When writing DataFlex code to process XML documents that use namespaces, you should use the namespace aware methods defined for the cXMLDOMDocument class.

For more information, refer to the section titled "Processing XML Documents with Namespaces" in the cXMLDOMDocument class documentation.