XSLT中的for-each怎么用 XSLT循环遍历节点教程

xsl:for-each 是 XSLT 中基于 XPath“拉取”节点的直接循环工具,每次切换当前上下文,支持 position() 序号、mod 奇偶判断、sort 排序、position()≤N 限定数量,XSLT 1.0 需 key+generate-id() 去重,2.0+ 支持 for-each-group 分组。

xsl:for-each 是 XSLT 里最常用、最直接的循环工具,它不依赖模板匹配,而是用 XPath 表达式“拉取”节点,然后对每个节点依次处理。用法简单,但细节决定效果——比如上下文切换、位置控制、去重或排序,稍不注意就容易出错。

基础写法:选中节点并逐个处理

核心就一句:...。select 是必需属性,必须写一个合法的 XPath,指向你要遍历的一组节点。

  • 每次进入循环,当前节点(.)自动切换为被选中的那个节点,所有相对路径(如 titleartist)都基于它解析
  • 循环体内部可以嵌套任意 XSLT 指令:value-of、if、sort、attribute 等
  • 常见错误是 select 写成绝对路径却忽略根结构,比如 XML 根是 ,那就得写 catalog/cd,不能只写 cd

加序号、奇偶行、倒序这些实用技巧

不用额外变量,靠内置函数就能搞定常见排版需求。

  • 显示序号:用 position(),从 1 开始计数,例如
  • 奇偶行变色:结合 position() mod 2 判断,值为 1 是奇数行,0 是偶数行
  • 倒序排列:在 for-each 内部加
  • 只取前 N 条:把条件写进 select,比如 book[position()

去重和分组:XSLT 1.0 和 2.0 差别很大

原生 for-each 不自带去重,得靠组合技巧;XSLT 2.0+ 提供了更简洁的方案。

  • XSLT 1.0 去重:定义 + generate-id() 配合使用,语法略绕但稳定可靠
  • XSLT 2.0+ 分组:直接用 ,再用 current-grouping-key()current-group() 拿数据
  • 注意:group-by 的值必须是字符串类型,数值或日期需用 string() 或 format-date() 转一下

小心上下文丢失和嵌套陷阱

for-each 会改变当前上下文,但不会影响外层模板的上下文。嵌套时容易搞混“谁是谁的子节点”。

  • 在循环内想访问父级数据(比如总记录数),要用 count(/catalog/cd) 这类绝对路径,而不是 count(cd)
  • 嵌套 for-each 时,内层的 position() 是相对于内层节点集的,不是全局序号
  • 避免在 for-each 里反复写相同逻辑,可抽成 提高可读性

基本上就这些。写 for-each 不复杂,但容易忽略上下文和 XPath 范围,多调试几次 select 表达式,基本就稳了。