Mastering XML and Mobile Markup Systems
Complex Namespace Management
The Real Meaning of Namespaces
At its core, an XML namespace is a simple mapping. You bind a short, convenient prefix to a globally unique Uniform Resource Identifier (URI). The prefix is just a local nickname; the URI is the true, unambiguous name for a vocabulary. Think of it like a contact in your phone. You might save a number under the nickname "Mom," but the actual phone number is the unique identifier that ensures you call the right person.
Crucially, the namespace URI doesn't need to point to a live web page. Its only job is to be unique. This prevents conflicts when you mix different XML vocabularies in the same document.
<root xmlns:bk="http://www.example.com/books">
<bk:book>
<bk:title>The Art of XML</bk:title>
<bk:author>Jane Doe</bk:author>
</bk:book>
</root>
In this example, the prefix bk is bound to the URI http://www.example.com/books. Every element prefixed with bk: belongs to that specific vocabulary.
Scoping and Inheritance Rules
A namespace declaration applies to the element where it's defined and all of its children. This is called scoping. You can declare a namespace on the root element, and it will apply to the entire document unless overridden by a new declaration on a nested element.
A default namespace is one that applies to elements without a prefix. You declare it using the xmlns attribute without a colon and prefix.
<order xmlns="http://www.example.com/orders"
xmlns:prod="http://www.example.com/products">
<item orderId="A123">
<prod:name>Widget</prod:name>
<prod:sku>W-001</prod:sku>
</item>
</order>
Here, <order> and <item> are in the http://www.example.com/orders namespace because it's the default. The <name> and <sku> elements belong to the http://www.example.com/products namespace because they use the prod prefix.
One critical rule to remember: attributes never inherit the default namespace from their parent element. In the example above, the orderId attribute is not in any namespace. To place an attribute in a namespace, you must explicitly give it a prefix.
Handling Collisions
The primary purpose of namespaces is to prevent when combining XML from different sources. Imagine one vocabulary defines <table> for furniture and another defines <table> for data. Without namespaces, a processor wouldn't know which is which.
Namespaces provide the necessary context.
<doc xmlns:furn="http://www.example.com/furniture"
xmlns:html="http://www.w3.org/TR/html4/">
<furn:table>
<furn:name>Coffee Table</furn:name>
<furn:material>Oak</furn:material>
</furn:table>
<html:table>
<html:tr>
<html:td>Cell 1</html:td>
<html:td>Cell 2</html:td>
</html:tr>
</html:table>
</doc>
There are two reserved prefixes you cannot use: xmlns and xml. The xmlns prefix is used for declaring namespaces themselves. The is bound to a special URI (http://www.w3.org/XML/1998/namespace) and is used for attributes that have universal meaning across all XML documents, such as xml:lang for language codes or xml:space for preserving white space.
While XML 1.0 lets you override a namespace prefix, you can't completely remove a namespace from a child element's scope. XML 1.1 introduced namespace undeclaration to solve this. By setting a prefix or the default namespace to an empty string (xmlns:prefix=""), you can remove that namespace from the scope of an element and its descendants. This provides more flexibility, particularly when composing documents from different, self-contained fragments.
What is the primary purpose of using XML namespaces?
Consider the following XML snippet:
<order xmlns="http://www.example.com/orders" orderId="A123">
<item xmlns:p="http://www.example.com/products">
<p:name>Widget</p:name>
</item>
</order>
Which part of this XML is NOT in any namespace?