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.