group-by是XSLT 2.0中xsl:for-each-group的必需属性,用于按表达式值自动分组;需配合current-group()和current-grouping-key()使用,并注意空值、大小写等边界处理。
在XSLT 2.0中,group-by 是 xsl:for-each-group 指令的核心属性,用于按指定表达式对节点序列分组。它不依赖预排序,也不要求数据结构特殊,只要表达式能为每个项目生成一个可比较的值(如字符串、数字、日期等),就能自动聚类。
分组必须包裹在 xsl:for-each-group 中,不能单独使用 group-by:
select 属性指定要遍历的节点序列(比如 //item)group-by 属性指定分组依据的表达式(比如 @category 或 upper-case(name))current-group() 获取全部成员,用 current-grouping-key() 获取当前组的键值按属性值分组:
组键是每个 product 的 type 属性值,相同 @type 的产品归为一组。
按子元素文本分组:
以 customer/name 的字符串值为键,把同一客户的所有订单归为一组。
按计算结果分组(如首字母、年份):
按书名首字母分组;也可用 year-from-date(@pubdate) 按出版年份分组。
进入每组后,通常需要输出汇总或列表:
输出组名(如 “Fiction”) 遍历该组所有节点count(current-group()) 得到组大小,sum(current-group()/price) 算总价group-by="generate-id()" + 预处理,但更推荐先用 xsl:key 或 distinct-values 配合 for-each空值和空白会影响分组结果:
group-by="@status" 中,缺失 @status 的节点会被分到同一个隐式空组(键为 xs:string(()),即空序列)group-by="normalize-space(@status)" 去首尾空格,或 group-by="if(@status
) then @status else 'unknown' 统一缺省值upper-case(@role) 或 lower-case()
基本上就这些。掌握 current-group() 和 current-grouping-key() 这两个核心函数,再结合实际路径或计算表达式,就能灵活应对大多数分组需求。不复杂但容易忽略空值和大小写细节。