---
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
```
**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.