Skip to content

XML Namespaces and URIs — Complete Guide to Qualified Names

DodaTech Updated 2026-06-23 7 min read

In this tutorial, you'll learn about XML Namespaces and URIs. We cover key concepts, practical examples, and best practices.

XML namespaces use URIs to uniquely identify element and attribute vocabularies, preventing name collisions when combining XML from different sources — using prefixes or default namespace declarations to qualify every name.

What You'll Learn

  • How namespace URIs disambiguate element names
  • Declaring default vs prefixed namespaces with xmlns
  • Namespace scope and inheritance rules
  • Handling namespaces in XPath and parsing

Why XML Namespaces Matter

When you combine an invoice XML from accounting and a product catalog from inventory, both might use — but they mean different things. Namespaces let you distinguish them. Every major XML format uses namespaces: SOAP, XSLT, SVG, XML Schema, RSS, and Atom. Doda Browser uses namespaced XML for its bookmark format, separating HTML metadata from browser-specific configuration.

Learning Path

flowchart LR
  A[XML Basics] --> B[XML DTD Validation]
  B --> C[XML Namespaces URIs
You are here] C --> D[XML Schema XSD] D --> E[SOAP & WSDL]

Namespace Declaration Syntax

A namespace is declared using the xmlns attribute:

<!-- Prefixed namespace -->
<bk:library xmlns:bk="http://books.example.com/ns">
    <bk:book>
        <bk:title>The Hobbit</bk:title>
    </bk:book>
</bk:library>

<!-- Default namespace (no prefix) -->
<library xmlns="http://books.example.com/ns">
    <book>
        <title>The Hobbit</title>
    </book>
</library>

<!-- Multiple namespaces -->
<library xmlns:bk="http://books.example.com/ns"
         xmlns:inv="http://inventory.example.com/ns">
    <bk:book>
        <bk:title>The Hobbit</bk:title>
        <inv:stock units="12"/>
    </bk:book>
</library>

Default vs Prefixed Namespaces

Aspect Default Namespace Prefixed Namespace
Declaration xmlns="URI" xmlns:prefix="URI"
Element usage Unqualified name prefix:element
Scope All unqualified descendants Only elements with the prefix
Attributes Not affected (no default) Must be explicitly prefixed
<!-- Demonstrating both -->
<catalog xmlns="http://books.example.com/ns"
         xmlns:meta="http://metadata.example.com/ns">
    <!-- book is in the default namespace -->
    <book>
        <title>The Hobbit</title>
        <!-- meta:date uses the prefixed namespace -->
        <meta:date added="2026-06-23"/>
    </book>
</catalog>

Attributes without prefixes are always in no namespace — even inside a default namespace scope.

Namespace Scope and Inheritance

Namespaces apply to the declaring element and all descendants unless overridden:

<root xmlns:bk="http://books.example.com/ns">
    <!-- bk: prefix works here -->
    <bk:book>
        <bk:title>The Hobbit</bk:title>
        <!-- Override: inside here, local is the default -->
        <local:notes xmlns:local="http://local.example.com/ns">
            <local:note>A classic fantasy novel.</local:note>
        </local:notes>
    </bk:book>
    <!-- bk: prefix still works here -->
    <bk:book>
        <bk:title>1984</bk:title>
    </bk:book>
</root>

Scope Rules

  1. A namespace declaration applies to the element where it appears
  2. It is inherited by all descendant elements
  3. A descendant can override with its own xmlns declaration
  4. The same prefix can be redeclared to a different URI (confusing — avoid)

URI vs URL — What the Namespace URI Actually Does

A namespace URI does not need to point to a real resource. It is just a unique identifier:

<!-- These are all valid namespace URIs -->
xmlns:book="http://books.example.com/ns/2026"
xmlns:book="urn:isbn:978-0547928227"
xmlns:book="http://example.com/books#schema"

The URI disambiguates names. Two elements with the same local name but different namespace URIs are completely different:

Element Namespace URI Identity
{http://books.example.com}price books Book price
{http://furniture.example.com}price furniture Furniture price
{http://inventory.example.com}price inventory Wholesale cost

They are unrelated — even though they share the local name price.

Working with Namespaces in XML Parsing

Python (lxml)

from lxml import etree

xml_data = """<?xml version="1.0" encoding="UTF-8"?>
<library xmlns:bk="http://books.example.com/ns"
         xmlns:inv="http://inventory.example.com/ns">
    <bk:book>
        <bk:title>The Hobbit</bk:title>
        <bk:author>J.R.R. Tolkien</bk:author>
        <inv:stock>12</inv:stock>
    </bk:book>
</library>"""

root = etree.fromstring(xml_data)

# Define namespace map
ns = {'bk': 'http://books.example.com/ns',
      'inv': 'http://inventory.example.com/ns'}

# Query with namespaced XPath
titles = root.xpath('//bk:title/text()', namespaces=ns)
print('Titles:', titles)

stocks = root.xpath('//inv:stock/text()', namespaces=ns)
print('Stock counts:', stocks)

# Expected output:
# Titles: ['The Hobbit']
# Stock counts: ['12']

JavaScript (Browser)

const xmlString = `<?xml version="1.0" encoding="UTF-8"?>
<library xmlns:bk="http://books.example.com/ns"
         xmlns:inv="http://inventory.example.com/ns">
    <bk:book>
        <bk:title>The Hobbit</bk:title>
        <inv:stock units="12"/>
    </bk:book>
</library>`;

const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlString, "text/xml");

// Define namespace resolver
function nsResolver(prefix) {
    const nsMap = {
        "bk": "http://books.example.com/ns",
        "inv": "http://inventory.example.com/ns"
    };
    return nsMap[prefix] || null;
}

// Query using XPath with namespace resolver
const titles = xmlDoc.evaluate(
    "//bk:title/text()", xmlDoc, nsResolver,
    XPathResult.ANY_TYPE, null
);

const result = [];
let node;
while ((node = titles.iterateNext()) !== null) {
    result.push(node.textContent);
}
console.log("Titles:", result);

// Expected output:
// Titles: ['The Hobbit']

Real-World Namespace Examples

SOAP Envelope

<?xml version="1.0"?>
<soap:Envelope
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <soap:Body>
        <m:GetPrice xmlns:m="http://books.example.com/prices">
            <m:Item>978-0547928227</m:Item>
        </m:GetPrice>
    </soap:Body>
</soap:Envelope>

XSLT Stylesheet

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:bk="http://books.example.com/ns"
    xmlns="http://www.w3.org/1999/xhtml">

    <xsl:template match="bk:book">
        <div class="book">
            <h2><xsl:value-of select="bk:title"/></h2>
            <p>by <xsl:value-of select="bk:author"/></p>
        </div>
    </xsl:template>
</xsl:stylesheet>

SVG

<svg xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink"
     width="200" height="200">
    <circle cx="100" cy="100" r="50" fill="blue"/>
    <text x="100" y="105" text-anchor="middle"
          fill="white">DodaTech</text>
</svg>

Security Angle

Namespace injection attacks occur when user-controlled input influences namespace prefixes or URIs. An attacker might craft XML that redeclares a trusted namespace prefix to point to a malicious URI, causing parsers to misinterpret element meanings. Durga Antivirus Pro validates namespace URIs against an allowlist during XML threat signature processing, rejecting any document that uses unapproved namespace declarations. Always verify namespace declarations when processing untrusted XML.

Common Mistakes

1. Confusing the namespace URI with a URL

The namespace URI http://example.com/ns does not need to be a real web page. It is just a unique identifier string. Browsing to it may return 404.

2. Forgetting that unprefixed attributes are never in a namespace

Even inside a default namespace, attribute="value" is in no namespace. Only explicitly prefixed attributes like ns:attr="value" are namespaced.

3. Trying to use //title with namespaced XML

If the XML uses a default namespace, //title won't match. You need //ns:title with the namespace prefix mapped.

4. Redeclaring the same prefix to different URIs

This is valid but extremely confusing. Never redeclare a prefix to point to a different URI in the same document.

Practice Questions

  1. What is the purpose of a namespace URI in XML? To uniquely identify a vocabulary of element and attribute names, preventing collisions when combining XML from different sources.

  2. What is the difference between default and prefixed namespaces? Default namespaces apply to all unqualified descendant elements. Prefixed namespaces require an explicit prefix on every element.

  3. Are unprefixed attributes affected by a default namespace? No. Unprefixed attributes are always in no namespace, regardless of any default namespace declaration.

Challenge: Create an XML document that combines two namespaces — one for book metadata (title, author, ISBN) and one for inventory data (warehouse, stock level, reorder threshold) — then write an XPath query that extracts only the inventory information.

FAQ

What is an XML namespace?

An XML namespace is a URI-based identifier that disambiguates element and attribute names from different vocabularies, preventing name collisions.

How do I declare a namespace in XML?

Use the xmlns attribute: xmlns:prefix="URI" for prefixed namespaces, or xmlns="URI" for default namespaces.

What is the difference between a namespace and a prefix?

A namespace is the URI that uniquely identifies a vocabulary. A prefix is a shorthand alias for that URI in the XML document.

Can two elements with the same name but different namespaces be different?

Yes. Elements are identified by their expanded name (namespace URI + local name), so bk:price and inv:price are completely different.

How do I query namespaced XML with XPath?

Map prefixes to namespace URIs in your XPath engine, then use prefix:element in your XPath expressions.

Do attributes inherit the default namespace?

No. Unprefixed attributes are always in no namespace, even when a default namespace is declared on the parent element.

Try It Yourself

Query namespaced XML with xmllint:

# Extract titles from namespaced XML
xmllint --shell library.xml <<< "xpath //bk:title"

# Expected output depends on namespace registration
# Use --ns option to register namespace prefixes:
xmllint --ns bk=http://books.example.com/ns --xpath "//bk:title/text()" library.xml

Python namespace handling:

from lxml import etree

# Parse and register namespaces
tree = etree.parse("library.xml")
root = tree.getroot()

# Get all namespaces used in the document
nsmap = root.nsmap
print("Namespaces found:", nsmap)

# Register all namespaces for XPath
for prefix, uri in nsmap.items():
    etree.register_namespace(prefix or "default", uri)

# Expected output:
# Namespaces found: {'bk': 'http://books.example.com/ns', ...}

What's Next

Tutorial What You'll Learn
XML Basics — Complete Guide Foundational XML concepts
XPath Explained — Querying XML Navigate XML documents with path expressions
XML Schema Datatypes Advanced XSD datatypes and validation

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro. Updated 2026-06-23.

What's Next

Congratulations on completing this XML Namespaces and URIs tutorial! Here's where to go from here:

  • Practice daily — Consistency is more important than long study sessions
  • Build a project — Combine two XML vocabularies using namespaces
  • Explore related topics — Check out other XML tutorials in this category
  • Join the community — Discuss with other learners and share your progress

Remember: every expert was once a beginner. Keep coding!

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro