XML Namespaces
What are XML Namespaces?
XML Namespaces provide a method for avoiding element name conflicts in XML documents. They allow you to qualify element and attribute names by associating them with namespace URIs, enabling you to mix vocabularies from multiple XML applications in a single document.
The Problem Namespaces Solve
Consider this scenario: You want to create an XML document that includes both HTML table elements and database table information. Without namespaces, you'd have conflicting <table>
elements:
<!-- This creates ambiguity -->
<document>
<table><!-- HTML table? Database table? -->
<tr><td>HTML Cell</td></tr>
</table>
<table><!-- Which type of table is this? -->
<name>users</name>
<columns>5</columns>
</table>
</document>
Namespace Declaration
Namespaces are declared using the xmlns
attribute. The basic syntax is:
xmlns:prefix="namespace-uri"
Default Namespace
You can declare a default namespace without a prefix:
<?xml version="1.0" encoding="UTF-8"?>
<book xmlns="http://example.com/book">
<title>Learning XML</title>
<author>John Doe</author>
</book>
Prefixed Namespaces
Using prefixes to distinguish between namespaces:
<?xml version="1.0" encoding="UTF-8"?>
<document xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:db="http://example.com/database">
<html:table>
<html:tr>
<html:td>HTML Cell Content</html:td>
</html:tr>
</html:table>
<db:table>
<db:name>users</db:name>
<db:columns>5</db:columns>
</db:table>
</document>
Namespace URI vs URL
The namespace URI is an identifier, not necessarily a web address. While it often looks like a URL, it doesn't need to point to an actual web resource:
<!-- These are valid namespace URIs -->
xmlns:book="http://example.com/book/2023"
xmlns:inv="urn:company:inventory"
xmlns:math="http://www.w3.org/1998/Math/MathML"
Scope and Inheritance
Namespace declarations have scope - they apply to the element where they're declared and all its descendants:
<root xmlns:a="http://example.com/a">
<a:element1>
<a:nested>This element is in namespace 'a'</a:nested>
<element xmlns:b="http://example.com/b">
<a:stillInA>Still in namespace 'a'</a:stillInA>
<b:inB>Now in namespace 'b'</b:inB>
</element>
</a:element1>
</root>
Multiple Namespaces Example
Here's a practical example mixing XHTML and SVG:
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:svg="http://www.w3.org/2000/svg">
<head>
<title>Mixed Namespaces</title>
</head>
<body>
<h1>Document with Embedded SVG</h1>
<svg:svg width="100" height="100">
<svg:circle cx="50" cy="50" r="40"
stroke="black" stroke-width="3" fill="red"/>
</svg:svg>
<p>Text after the SVG graphic.</p>
</body>
</html>
Namespace Attributes
Attributes can also be namespaced, but unprefixed attributes belong to no namespace:
<element xmlns:meta="http://example.com/metadata"
id="123" <!-- No namespace -->
meta:created="2023-07-10"> <!-- In 'meta' namespace -->
Content
</element>
Common Namespace URIs
Here are some frequently used namespace URIs:
Namespace | URI | Purpose |
---|---|---|
XHTML | http://www.w3.org/1999/xhtml | HTML in XML |
SVG | http://www.w3.org/2000/svg | Scalable Vector Graphics |
MathML | http://www.w3.org/1998/Math/MathML | Mathematical Markup |
SOAP | http://schemas.xmlsoap.org/soap/envelope/ | SOAP Web Services |
XML Schema | http://www.w3.org/2001/XMLSchema | XSD Schema Definition |
Best Practices
Use Meaningful URIs
<!-- Good: Descriptive and version-specific -->
xmlns:book="http://company.com/schemas/book/v2.0"
<!-- Avoid: Too generic -->
xmlns:ns1="http://example.com/ns1"
Consistent Prefixes
Use consistent, descriptive prefixes across your documents:
<!-- Consistent across documents -->
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:db="http://company.com/database"
xmlns:auth="http://company.com/authentication"
Minimize Namespace Declarations
Declare namespaces at the highest level possible to avoid repetition:
<!-- Efficient: Declare once at root -->
<root xmlns:a="http://example.com/a"
xmlns:b="http://example.com/b">
<a:element1/>
<b:element2/>
<a:element3/>
</root>
Working with Namespaces in Code
JavaScript (DOM)
// Creating namespaced elements
const doc = document.implementation.createDocument(
'http://example.com/myns', 'root', null
);
// Selecting by namespace
const elements = doc.getElementsByTagNameNS(
'http://example.com/myns', 'element'
);
PHP
// Creating namespaced XML
$doc = new DOMDocument();
$root = $doc->createElementNS('http://example.com/ns', 'ns:root');
$doc->appendChild($root);
// XPath with namespaces
$xpath = new DOMXPath($doc);
$xpath->registerNamespace('ns', 'http://example.com/ns');
$nodes = $xpath->query('//ns:element');
Common Pitfalls
Default Namespace Scope
Remember that default namespaces don't apply to attributes:
<root xmlns="http://example.com/default">
<!-- Element is in default namespace -->
<element attribute="value"> <!-- Attribute has NO namespace -->
Content
</element>
</root>
Namespace URI Matching
Namespace matching is exact - even small differences matter:
<!-- These are DIFFERENT namespaces -->
xmlns:a="http://example.com/ns"
xmlns:b="http://example.com/ns/" <!-- Note the trailing slash -->
Validation with Namespaces
When using XML Schema with namespaces, specify the target namespace:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://example.com/book"
xmlns:book="http://example.com/book">
<xs:element name="book" type="book:BookType"/>
<xs:complexType name="BookType">
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="author" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
Conclusion
XML Namespaces are essential for creating modular, reusable XML vocabularies. They enable you to combine multiple XML schemas in a single document while avoiding naming conflicts. Mastering namespaces is crucial for working with complex XML systems and web services.
Next Steps
- Learn about XML Schema (XSD) for advanced validation
- Explore XPath for namespace-aware node selection
- Study XSLT for namespace-aware transformations