Grouping is one of the most powerful features introduced in XSLT 2.0. Before it, grouping in XSLT 1.0 required the Muenchian method — a clever but verbose technique involving keys and node-set comparisons. In 2.0, xsl:for-each-group makes grouping straightforward.
Basic grouping with group-by
group-by groups nodes that share the same value for a given expression. The result is one iteration per distinct group value.
Input:
DE120
US85
DE200
FR60
US140
Stylesheet:
Output:
2320
160
2225
Key functions inside for-each-group:
-
current-grouping-key()— returns the value that defines the current group -
current-group()— returns the sequence of all nodes in the current group
Nested grouping
Groups can be nested. Group orders by country, then within each country by status:
group-adjacent
Groups consecutive nodes that share the same key value. Unlike group-by, it starts a new group when the key changes, even if the same key appeared earlier. This is useful for processing structured text or segmented data.
Starting
Processing
Failed
Retrying
Done
This produces three blocks: two INFO (positions 1-2), one ERROR (3-4), one INFO (5). With group-by, the two INFO groups would be merged into one.
group-starting-with and group-ending-with
These group nodes based on a pattern match rather than a key value. Every time a node matches the pattern, a new group starts (or ends).
group-starting-with example — treat every ## as the start of a section:
<xsl:value-of select="self::h2"/>
group-ending-with example — group lines until a blank line:
Computing aggregates
current-group() returns a sequence, so you can apply any XPath aggregate function directly:
Try it in XSLT Playground
Paste any of the examples above into XSLT Playground with version set to 2.0 or 3.0. Grouping is one of the features that benefits most from live testing — you can immediately see how changing the grouping key or switching between group-by and group-adjacent affects the output structure.
Top comments (0)