--- title: "XSLT grouping with xsl:for-each-group: complete guide" description: "How to group XML nodes in XSLT 2.0 using for-each-group. Covers group-by, group-adjacent, group-starting-with, and group-ending-with with examples." date: 2025-04-01T00:00:00Z tags: ["xslt", "grouping", "xslt2", "xpath"] --- 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:** ```xml DE120 US85 DE200 FR60 US140 ``` **Stylesheet:** ```xml ``` **Output:** ```xml 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: ```xml ``` ## 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. ```xml Starting Processing Failed Retrying Done ``` ```xml ``` 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: ```xml
<xsl:value-of select="self::h2"/>
``` **group-ending-with example** — group lines until a blank line: ```xml ``` ## Computing aggregates `current-group()` returns a sequence, so you can apply any XPath aggregate function directly: ```xml ``` ## Try it in XSLT Playground Paste any of the examples above into [XSLT Playground](https://xsltplayground.com) 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.