XML Core
Namespaces & Modular XML
When an XML document combines vocabularies from multiple sources, names collide. Namespaces solve this by associating element names with a URI, making every name globally unique and enabling modular XML design.
The Problem Namespaces Solve
When you combine XML vocabularies from different sources in one document, element names collide. Consider a document mixing book catalog data with XHTML for display:
<!-- PROBLEM: which <title> is which? -->
<report>
<title>Annual Report 2026</title>
<html>
<head><title>Page Title</title></head>
</html>
</report>A parser cannot distinguish which <title> belongs to which vocabulary. Namespaces tag each element with its origin, making every qualified name globally unique.
Namespace Declaration Syntax
<report xmlns="http://example.com/report"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:chart="http://example.com/chart">
<title>Annual Report 2026</title> <!-- default namespace -->
<html:title>Page Title</html:title> <!-- html namespace -->
<chart:chart>
<chart:title>Revenue Growth</chart:title> <!-- chart namespace -->
</chart:chart>
</report>How It Works
Default namespace — xmlns="URI" — all unqualified elements belong to this namespace. No prefix clutter, most readable when a document uses primarily one vocabulary.
Prefixed namespace — xmlns:prefix="URI" — elements with that prefix (html:title, chart:title) belong to the associated namespace. Explicit and unambiguous.
The URI is just an identifier — the parser never fetches it. A namespace URI is a string that guarantees uniqueness. By convention it is a URL the organization controls, but it does not need to resolve to a web page. http://www.w3.org/2001/XMLSchema has been a namespace URI for 25 years and will never change.
Namespace scope — a declaration applies to the element it appears on and all its descendants, unless overridden by a new declaration on a descendant element.
Changing the Default Namespace
<root xmlns="urn:vocabulary-one">
<child>in vocabulary-one</child>
<container xmlns="urn:vocabulary-two">
<child>in vocabulary-two</child> <!-- different namespace -->
</container>
<child>back to vocabulary-one</child>
</root>You can switch the default namespace on any element. This is useful for embedding fragments of one vocabulary inside another.
Undeclaring a Namespace
xmlns="" removes the default namespace for an element and its descendants — useful when child elements should have no namespace.
Attributes and Namespaces
Unqualified attributes (no prefix) do NOT belong to any namespace, even when the element they are on has a default namespace. This is a subtle but important rule:
<book xmlns="http://example.com/books" id="bk101">
<!-- id attribute is in NO namespace, not in the books namespace -->
</book>To put an attribute in a namespace, use an explicit prefix: <element xml:lang="en">. Standard attributes like xml:lang and xml:space use the xml prefix which is predefined in every XML processor.
Namespaces in Real-World XML
Every major XML vocabulary declares its namespace in the root element. Recognizing these URIs tells you immediately which format you are reading:
| Namespace URI | Format | Prefix |
|---|---|---|
| http://www.w3.org/2001/XMLSchema | XML Schema (XSD) | xs: |
| http://www.w3.org/1999/XSL/Transform | XSLT stylesheets | xsl: |
| http://www.w3.org/1999/xhtml | XHTML documents | (default) |
| http://www.w3.org/2000/svg | SVG graphics | (default) |
| http://www.w3.org/2003/05/soap-envelope | SOAP 1.2 | soap: |
| http://www.w3.org/2005/Atom | Atom feeds | (default) |
| http://www.sitemaps.org/schemas/sitemap/0.9 | sitemap.xml | (default) |
| http://schemas.openxmlformats.org/wordprocessingml/2006/main | .docx content | w: |
| http://schemas.openxmlformats.org/spreadsheetml/2006/main | .xlsx content | x: |
XSD with Namespaces
When you add namespaces to your XML documents, your XSD schema must reference the target namespace:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://example.com/books"
xmlns:bk="http://example.com/books"
elementFormDefault="qualified">
<!-- Schema elements now belong to the books namespace -->
</xs:schema>Reference in the document:
<catalog xmlns="http://example.com/books"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://example.com/books catalog.xsd">Modular XML Design
Namespaces enable composing documents from reusable vocabularies — the same principle as module systems in programming.
`<xs:import>` — brings in definitions from a different namespace:
<xs:import namespace="http://example.com/common"
schemaLocation="common-types.xsd"/>`<xs:include>` — includes definitions from the same namespace (different file). Enables splitting large schemas into manageable files.
Common Mistakes
Assuming the namespace URI must be fetchable. It is just a unique string. http:// is convention, not a requirement.
Forgetting that default namespaces don't apply to attributes. Unqualified attributes are always in no namespace.
Confusing prefix with namespace. The prefix is just an abbreviation. The namespace is the URI. Two documents using bk: for different URIs have nothing in common. Two documents using different prefixes for the same URI are in the same namespace.
Using a prefix before declaring it. Results in a well-formedness error, not just a validation error.
See [XPath: Querying XML Documents](/tutorials/xml-fundamentals/xpath-querying) where namespace-aware XPath is essential for querying documents that use namespaces — namespace handling is one of the most common XPath pitfalls.
Example
<!-- Mixed vocabulary document -->
<invoice xmlns="http://example.com/invoice"
xmlns:addr="http://example.com/address"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://example.com/invoice invoice.xsd">
<id>INV-2026-0042</id>
<addr:billing>
<addr:street>123 Main St</addr:street>
<addr:city>Springfield</addr:city>
<addr:country>US</addr:country>
</addr:billing>
<total currency="USD">249.00</total>
</invoice>
<!-- SVG with namespace -->
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="#E97627"/>
</svg>