How xsl:for-each Iterates Over XML Node-Sets
The xsl:for-each element in XSLT is a control-flow
instruction designed to iterate over a collection of XML nodes matching
an XPath expression. This article explains the underlying mechanics of
how xsl:for-each evaluates node-sets, alters the evaluation
context for each iteration, applies sorting rules, and processes
template bodies sequentially to generate output.
1. Node-Set Selection via XPath
Iteration begins by evaluating the expression defined in the
mandatory select attribute. The XSLT processor evaluates
this XPath expression relative to the current context node to identify a
sequence or node-set. If the expression matches zero nodes, the
xsl:for-each block is skipped entirely. If one or more
nodes match, the processor creates an internal list of candidate nodes
for processing.
2. Establishing Context: Node, Position, and Size
For every node in the selected set, the processor temporarily changes
the execution context. Inside the xsl:for-each block: *
Current Context Node (.): Switches
automatically to the individual node currently being processed, allowing
relative XPath queries (e.g., ./title or @id)
to target child nodes or attributes of that specific item. *
Context Position (position()): Returns the
1-based index of the current node within the active sequence. *
Context Size (last()): Returns the total
number of nodes in the selected node-set.
3. Ordering and the Role of
xsl:sort
By default, xsl:for-each processes nodes in
document order—the order in which the elements appear
in the source XML document.
However, you can alter this processing sequence by placing one or
more xsl:sort elements as immediate children at the
beginning of the xsl:for-each block. When
xsl:sort is present, the processor reorders the node-set
according to the specified sort keys, data types (text or
number), and order (ascending or
descending) before executing the loop body. The
position() function then reflects the sorted order rather
than the original document order.
4. Template Body Execution
Once the node-set is determined and ordered, the XSLT engine executes
the child instructions inside the xsl:for-each container
once for each node sequentially: 1. The engine sets the context node to
the first item in the list. 2. It evaluates all literal result elements
and XSLT instructions (such as xsl:value-of,
xsl:apply-templates, or conditional logic) contained within
the block. 3. The generated output is written to the result tree. 4. The
engine advances to the next node and repeats the process until the
entire set has been traversed.
5. Context Restoration
After iterating through the final node in the set, execution exits
the xsl:for-each instruction. The processor automatically
restores the context node, context position, and context size to the
state they were in immediately before the xsl:for-each
block was entered.