How Does the XSLT Select Attribute Work?
The select attribute in XSLT serves as the primary
bridge between an XSL stylesheet and XPath expressions, dictating which
nodes, atomic values, or computational results an element should
process. While its universal purpose is to evaluate an XPath expression
against the current context node, its behavior, required data type, and
output vary significantly depending on the parent element. This guide
breaks down how the select attribute operates across major
XSLT elements, covering node navigation, value extraction, loop
iteration, variable assignment, and sorting.
Extracting Data with
xsl:value-of
When used inside xsl:value-of, the select
attribute evaluates an XPath expression and converts the result into a
string to insert into the result tree.
In XSLT 1.0, if the expression evaluates to a node-set,
xsl:value-of extracts the string-value of only the first
node in document order. In XSLT 2.0 and later versions, selecting a
sequence of nodes or items will output all item values separated by a
space (or a custom delimiter defined by the separator
attribute).
<!-- Selects and outputs the text value of the title element -->
<xsl:value-of select="book/title" />Delegating
Processing with xsl:apply-templates
In xsl:apply-templates, the select
attribute specifies a node-set (or sequence) to which the processor
should apply matching templates.
If the select attribute is omitted, the processor
defaults to selecting all child nodes of the current context node
(select="node()"). Supplying a specific XPath expression
narrows the processing scope, filters out unwanted elements, or sorts
the matched nodes before processing begins.
<!-- Applies templates only to active employee elements -->
<xsl:apply-templates select="department/employee[@status='active']" />Iterating Over
Node-Sets with xsl:for-each
The select attribute in xsl:for-each
defines the collection of nodes over which a loop executes.
During each iteration, the processor updates the context node to the
individual node currently being evaluated. This changes the baseline for
any relative XPath expressions executed inside the body of the
xsl:for-each block.
<xsl:for-each select="catalog/item">
<!-- The context node is now 'item' -->
<li><xsl:value-of select="name" /></li>
</xsl:for-each>Assigning Data
with xsl:variable and xsl:param
Within xsl:variable and xsl:param, the
select attribute determines the value and data type bound
to the variable name.
Using the select attribute assigns native XPath data
types such as node-sets, booleans, numbers, or strings:
<xsl:variable name="itemCount" select="count(catalog/item)" />
<xsl:variable name="selectedNodes" select="catalog/item[@featured='true']" />If the select attribute is omitted and content is
provided inside the element body, XSLT constructs a Result Tree Fragment
(in XSLT 1.0) or a document node containing text (in XSLT 2.0+), which
consumes more memory and behaves differently than a direct node
reference.
Deep Copying with
xsl:copy-of
Unlike xsl:value-of, which flattens selected nodes into
a string, xsl:copy-of uses its select
attribute to perform a deep copy of the selected node-set, preserving
all child elements, attributes, and text nodes into the result tree
unchanged.
<!-- Copies the entire metadata subtree into the output -->
<xsl:copy-of select="document/metadata" />Ordering Output with
xsl:sort
When placed inside xsl:apply-templates or
xsl:for-each, xsl:sort uses its
select attribute to determine the sorting key for the
surrounding node collection. The XPath expression is evaluated relative
to each individual node in the collection being iterated or
processed.
<xsl:for-each select="catalog/item">
<xsl:sort select="price" data-type="number" order="ascending" />
<p><xsl:value-of select="name" />: <xsl:value-of select="price" /></p>
</xsl:for-each>Understanding Context Evaluation
Across all elements, the evaluation of the select
attribute depends entirely on the current context:
- Context Node: Relative XPath paths inside
selectresolve against the node currently being processed by the enclosing template or loop. - Context Position: Functions like
position()inside predicate selectors resolve relative to the sequence defined by the enclosing instruction. - Global Scope: Elements at the top level of a
stylesheet (such as global variables) evaluate their
selectattributes against the root node of the source document.