How to Dynamically Create Namespaces in XSLT?

In XSLT 2.0 and later versions, the <xsl:namespace> instruction allows developers to dynamically construct namespace nodes and bind them to result elements during transformation. This article explains the syntax, attributes, rules, and practical examples of <xsl:namespace>, demonstrating how to create namespace prefixes and URI bindings computed at runtime from source data, parameters, or expressions.

The Need for Dynamic Namespaces

In XSLT 1.0, generating namespace declarations dynamically was difficult. Namespaces were typically inherited from the stylesheet or created implicitly by generating elements or attributes with prefixed names. When dynamic mapping required prefixes or URIs determined at runtime, developers often had to resort to cumbersome workarounds, such as using disable-output-escaping or creating temporary nodes.

XSLT 2.0 resolved this limitation by introducing the <xsl:namespace> element, giving fine-grained control over namespace node creation on the current element in the output tree.

Syntax and Core Attributes

The <xsl:namespace> element creates a namespace node on the currently enclosing result element. It supports two primary attributes:

The basic structure follows this format:

<xsl:namespace name="{$prefixVariable}" select="$uriVariable"/>

Alternatively, the URI can be provided as the content of the instruction:

<xsl:namespace name="{$prefixVariable}">
  <xsl:value-of select="$uriVariable"/>
</xsl:namespace>

Practical Example: Dynamic Mapping from Source XML

Consider an input document containing dynamic mappings for prefixes and namespaces that must be applied to an output document:

<!-- Source XML -->
<config>
  <mapping prefix="app" uri="http://example.com/app"/>
  <mapping prefix="data" uri="http://example.com/data"/>
</config>

An XSLT 2.0 or 3.0 stylesheet can iterate over these configuration nodes and attach the corresponding namespace definitions to the root element:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/config">
    <root>
      <xsl:for-each select="mapping">
        <xsl:namespace name="{@prefix}" select="@uri"/>
      </xsl:for-each>
      <content>Namespaces dynamically declared on root.</content>
    </root>
  </xsl:template>
</xsl:stylesheet>

When transformed, the resulting XML document contains the dynamically injected namespace declarations:

<root xmlns:app="http://example.com/app" 
      xmlns:data="http://example.com/data">
  <content>Namespaces dynamically declared on root.</content>
</root>

Declaring a Default Namespace

To declare or override a default namespace (an unprefixed namespace) dynamically, provide an empty string for the name attribute:

<xsl:template match="/">
  <root>
    <xsl:namespace name="" select="'http://example.com/default'"/>
    <child>Item</child>
  </root>
</xsl:template>

Usage Rules and Constraints

When working with <xsl:namespace>, several processor rules apply: