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:attribute>to inject dynamic or static attributes.<xsl:value-of>or plain text to supply text content.- Nested
<xsl:element>or literal elements for structured child hierarchies.
<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:
- If the
namespaceattribute is omitted, the prefix in thenameattribute is resolved against in-scope namespace declarations. - If the
namespaceattribute 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
- Validate Element Names: Ensure that values
evaluated inside the
name="{...}"attribute conform to valid XML QName naming conventions (no spaces, numbers as the initial character, or invalid symbols). - Use Literal Elements When Static: If the element
tag name is known beforehand, prefer literal result elements over
<xsl:element>to improve stylesheet readability and performance. - Combine with Attribute Sets: When dynamically
generated elements share standard attributes across multiple templates,
manage them centrally with
use-attribute-sets.