XML Namespaces

XML namespaces prevent element and attribute names from colliding when documents combine vocabularies from more than one source.

The Name Collision Problem

Because anyone can invent XML element names, two documents can easily use the same tag name to mean two different things. A <table> element might mean a piece of furniture in one document and a set of rows and columns of data in another. Combine both inside a single XML document, and a parser has no way to tell them apart.

A Naming Collision

<!DOCTYPE html>
<html>
<body>

<pre>
&lt;root&gt;
  &lt;table&gt;
    &lt;name&gt;African Coffee Table&lt;/name&gt;
    &lt;width&gt;80&lt;/width&gt;
    &lt;length&gt;120&lt;/length&gt;
  &lt;/table&gt;
  &lt;table&gt;
    &lt;tr&gt;
      &lt;td&gt;Apples&lt;/td&gt;
      &lt;td&gt;Bananas&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/table&gt;
&lt;/root&gt;
</pre>

</body>
</html>

Solving It With a Prefix and xmlns

The fix is to qualify each element name with a namespace, declared using the reserved xmlns attribute. The attribute's value is a URI that simply acts as a unique identifier — it doesn't need to point to a real, reachable page. Each element name is then prefixed to say which namespace it belongs to.

Disambiguating With Namespaces

<!DOCTYPE html>
<html>
<body>

<pre>
&lt;root&gt;
  &lt;f:table xmlns:f="https://example.com/furniture"&gt;
    &lt;f:name&gt;African Coffee Table&lt;/f:name&gt;
    &lt;f:width&gt;80&lt;/f:width&gt;
    &lt;f:length&gt;120&lt;/f:length&gt;
  &lt;/f:table&gt;

  &lt;h:table xmlns:h="https://example.com/report"&gt;
    &lt;h:tr&gt;
      &lt;h:td&gt;Apples&lt;/h:td&gt;
      &lt;h:td&gt;Bananas&lt;/h:td&gt;
    &lt;/h:tr&gt;
  &lt;/h:table&gt;
&lt;/root&gt;
</pre>

</body>
</html>

Default Namespaces

Instead of prefixing every single element, you can declare a default namespace on a parent element using xmlns without a prefix. Every unprefixed child element then belongs to that namespace automatically, until a nested element declares a different one.

A Default Namespace

<!DOCTYPE html>
<html>
<body>

<pre>
&lt;table xmlns="https://example.com/furniture"&gt;
  &lt;name&gt;African Coffee Table&lt;/name&gt;
  &lt;width&gt;80&lt;/width&gt;
  &lt;length&gt;120&lt;/length&gt;
&lt;/table&gt;
</pre>

</body>
</html>
  • A namespace is declared with the reserved attribute xmlns or xmlns:prefix.
  • The namespace value is a URI used purely as a unique name, not a fetchable web address.
  • A prefixed element, like f:table, belongs to whichever namespace its prefix was bound to.
  • A default namespace, declared with plain xmlns, applies to the element it's set on plus all of its unprefixed descendants.
  • Different elements can safely share a local name, like table, as long as they live in different namespaces.
Note: You'll frequently see namespace URIs that look like real web addresses, such as https://www.w3.org/1999/xhtml. That's a convention for guaranteeing uniqueness, borrowed from the fact that domain names are already globally unique — the URI is rarely, if ever, actually fetched by a parser.
Note: A common mistake is assuming a namespace URI must resolve to a real document describing the vocabulary. It doesn't have to exist as a retrievable resource at all — it only has to be unique.
FormSyntaxScope
Prefixed namespacexmlns:prefix="URI"Only elements or attributes written with that prefix
Default namespacexmlns="URI"The element it's declared on, plus unprefixed descendants

Exercise: XML Namespaces

What problem do XML namespaces primarily solve?