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属性指定分组依据的表达式(比如@categ或
oryupper-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() 这两个核心函数,再结合实际路径或计算表达式,就能灵活应对大多数分组需求。不复杂但容易忽略空值和大小写细节。

ory






