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:

xml
<!-- 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

xml
<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 namespacexmlns="URI" — all unqualified elements belong to this namespace. No prefix clutter, most readable when a document uses primarily one vocabulary.

Prefixed namespacexmlns: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

xml
<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:

xml
<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 URIFormatPrefix
http://www.w3.org/2001/XMLSchemaXML Schema (XSD)xs:
http://www.w3.org/1999/XSL/TransformXSLT stylesheetsxsl:
http://www.w3.org/1999/xhtmlXHTML documents(default)
http://www.w3.org/2000/svgSVG graphics(default)
http://www.w3.org/2003/05/soap-envelopeSOAP 1.2soap:
http://www.w3.org/2005/AtomAtom feeds(default)
http://www.sitemaps.org/schemas/sitemap/0.9sitemap.xml(default)
http://schemas.openxmlformats.org/wordprocessingml/2006/main.docx contentw:
http://schemas.openxmlformats.org/spreadsheetml/2006/main.xlsx contentx:

XSD with Namespaces

When you add namespaces to your XML documents, your XSD schema must reference the target namespace:

xml
<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:

xml
<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:

xml
<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

xml
<!-- 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>
Try it yourself — XML