How Does xsl:element Create XML Elements?

The <xsl:element> instruction in XSLT allows developers to generate output XML elements dynamically at runtime rather than hardcoding static tags into the stylesheet. By evaluating XPath expressions and Attribute Value Templates (AVTs), this instruction computes element names, prefixes, and namespace URIs on the fly based on the source document's data. This article explores how <xsl:element> works, its key attributes, practical code examples, and best practices for managing dynamic XML transformations.

The Role of <xsl:element> in XSLT

In standard XSLT stylesheets, output nodes are often written as literal result elements (such as <div> or <record>). While literal elements are straightforward, their names are fixed at compile time.

When the target element name depends on input XML values, configuration parameters, or business logic, literal result elements are insufficient. The <xsl:element> instruction bridges this gap by decoupling the creation of an element from its static tag definition.

Core Syntax and Attributes

The basic syntax for <xsl:element> relies on a few core attributes:

<xsl:element name="QName" namespace="uri" use-attribute-sets="NCName">
    <!-- Content: template body (text, attributes, child elements) -->
</xsl:element>

1. name (Required)

Specifies the qualified name (QName) of the element to create. It accepts an Attribute Value Template (curly braces {} enclosing an XPath expression), allowing the name to be determined dynamically from the source data.

2. namespace (Optional)

Defines the target namespace URI for the generated element. This attribute can also use AVTs to assign namespaces dynamically, overriding any default namespace declarations currently in scope.

3. use-attribute-sets (Optional)

Applies a predefined list of <xsl:attribute-set> rules directly to the newly generated element, simplifying the assignment of recurring attributes.

Static vs. Dynamic Element Generation

Understanding when to use <xsl:element> versus literal elements is critical for clean stylesheet design.

<!-- Static Literal Result Element -->
<item status="active">
    <xsl:value-of select="title" />
</item>

<!-- Dynamic Element using xsl:element -->
<xsl:element name="{name()}">
    <xsl:attribute name="status">active</xsl:attribute>
    <xsl:value-of select="title" />
</xsl:element>

In the dynamic example, {name()} evaluates the local name of the current context node, ensuring the output element mirrors the input tag regardless of what it is named.

Practical Implementation: Mapping Dynamic Tags

Consider an input document where XML tags are determined by a type code:

<fields>
    <field type="header">System Report</field>
    <field type="paragraph">Execution finished successfully.</field>
</fields>

To convert each <field> node into an element named after its @type attribute, <xsl:element> computes the tag name dynamically:

<xsl:template match="field">
    <xsl:element name="{@type}">
        <xsl:value-of select="." />
    </xsl:element>
</xsl:template>

Output generated:

<header>System Report</header>
<paragraph>Execution finished successfully.</paragraph>

Adding Attributes and Child Content

Elements created with <xsl:element> act as containers for child nodes. You can populate them using:

<xsl:element name="{$element-name}">
    <xsl:attribute name="id">
        <xsl:value-of select="generate-id()" />
    </xsl:attribute>
    <xsl:apply-templates select="node()" />
</xsl:element>

Namespace Resolution Rules

When dynamic prefixes or namespaces are involved, the XSLT processor determines the namespace mapping in one of two ways:

  1. If the namespace attribute is omitted, the prefix in the name attribute is resolved against in-scope namespace declarations.
  2. If the namespace attribute is supplied, the processor binds the dynamic element to that explicit URI, generating a corresponding namespace declaration in the output if necessary.

Common Best Practices