xsl:for-each-group 是 XSLT 2.0+ 按条件分组的核心指令,需指定 select 和 group-by 属性,支持 group-adjacent、group-starting-with 等多种分组方式,并依赖 current-grouping-key()、current-group() 等函数获取上下文。

xsl:for-each-group 是 XSLT 2.0 及以上版本中用于按指定条件对节点分组的核心指令,它比 XSLT 1.0 中手动模拟分组(如 Muenchian 方法)更直观、简洁、可靠。
基本语法和必需属性
最简形式需指定两个关键属性:
-
select:要遍历并分组的节点集(如
//item) -
group-by:分组依据的表达式(如
@category或substring(@date, 1, 4))
例如,按商品类别分组:
Category:
常用分组方式
除了 group-by,XSLT 还支持更灵活的分组策略:
- group-adjacent:只对相邻且值相同的节点分组(适合已排序数据,如日志按日期连续块分组)
-
group-starting-with:以匹配某模式的节点为每组起点(如把
当作章节头,其后所有非节点归入该组) -
group-ending-with:以匹配某模式的节点为每组终点(较少用,但可配合
group-starting-with实现区间分组)
关键辅助函数
在 xsl:for-each-group 内部,必须用这些函数获取分组上下文:
-
current-grouping-key():返回当前组的分组键值(即
group-by表达式的计算结果) - current-group():返回当前组内所有节点组成的序列(注意:不是原始顺序的子集,而是按文档顺序排列的该组全部节点)
-
position() 和 last():在
current-group()内有效,可用于标序号或判断首尾
注意事项和常见坑
使用时需留意几点:
- 必须用 XSLT 2.0+ 处理器(如 Saxon 9+、Altova RaptorXML),XSLT 1.0 不支持
-
group-by表达式结果会自动原子化(atomic),字符串比较默认区分大小写;如需忽略大小写,写成upper-case(@category) - 空值(
''或empty())会被当作独立的一组,必要时用normalize-space()预处理 - 若想保留原始顺序中各组的出现次序,无需额外操作;但组内节点顺序始终是文档顺序,不是 select 序列中的原始位置顺序
基本上就这些。掌握 group-by + current-group() + current-grouping-key() 这个组合,就能覆盖绝大多数分组需求。










