Sponsored

XSLT Reference

xsl:for-each

XSLT 1.0 element

Iterates over a node-set or sequence, applying the contained template body to each item in document order.

Syntax
<xsl:for-each select="node-set">

Description

xsl:for-each selects a set of nodes (or, in XSLT 2.0+, a sequence of items) and processes each one in turn. Within the loop body, the context node changes to the current item, so XPath expressions are evaluated relative to it.

It is the standard way to iterate over child elements or any repeated node structure when you do not want to use recursive template matching. The loop body can contain any sequence of XSLT instructions: output elements, xsl:value-of, nested xsl:for-each calls, conditionals, and so on.

An optional xsl:sort child element placed immediately inside xsl:for-each (before any other content) changes the processing order without altering the source document.

Parameters

ParameterTypeRequiredDescription
selectXPath expressionYesNode-set or sequence to iterate over.

Child element: xsl:sort

Place one or more xsl:sort elements as the first children to sort the selected set before processing.

AttributeDescription
selectXPath expression used as the sort key.
order"ascending" (default) or "descending".
data-type"text" (default) or "number".

Examples

Iterate over child elements

Input XML:

<?xml version="1.0" encoding="UTF-8"?>
<catalog>
  <item id="1"><name>Widget</name><price>9.99</price></item>
  <item id="2"><name>Gadget</name><price>24.99</price></item>
  <item id="3"><name>Doohickey</name><price>4.49</price></item>
</catalog>

Stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/catalog">
    <ul>
      <xsl:for-each select="item">
        <li>
          <xsl:value-of select="name"/>
          <xsl:text> — $</xsl:text>
          <xsl:value-of select="price"/>
        </li>
      </xsl:for-each>
    </ul>
  </xsl:template>
</xsl:stylesheet>

Output:

<ul>
  <li>Widget — $9.99</li>
  <li>Gadget — $24.99</li>
  <li>Doohickey — $4.49</li>
</ul>

Sorted iteration

Stylesheet (sort by price descending):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/catalog">
    <ul>
      <xsl:for-each select="item">
        <xsl:sort select="price" data-type="number" order="descending"/>
        <li>
          <xsl:value-of select="concat(name, ' — $', price)"/>
        </li>
      </xsl:for-each>
    </ul>
  </xsl:template>
</xsl:stylesheet>

Output:

<ul>
  <li>Gadget — $24.99</li>
  <li>Widget — $9.99</li>
  <li>Doohickey — $4.49</li>
</ul>

Notes

  • position() and last() inside the loop refer to the position within the selected set, not the original document position.
  • current() inside the loop returns the same node as . (the context node). It becomes useful when current() is called inside a predicate.
  • For grouping scenarios (e.g., group items by category) prefer xsl:for-each-group (XSLT 2.0+) over the Muenchian method with xsl:for-each.
  • Template rules (xsl:apply-templates) are generally more flexible and reusable than xsl:for-each; use xsl:for-each when the transformation logic is short and self-contained.

See also