XSLT 中的 for-each 是上下文切换而非循环,遍历 select 节点集并逐次改变当前上下文(.),支持 position()、last() 等上下文相关函数,但不支持 break/continue 且变量不可变;推荐优先使用 apply-templates + 匹配模板实现声明式处理。

XSLT 中的 for-each 不是“循环”而是“上下文切换”,它通过改变当前节点集来应用模板逻辑,写法简单但容易误用。
for-each 基本语法和作用
会遍历 select 指定的节点集合,每次迭代时,当前上下文(.)变为该节点,所有相对路径、函数(如 position()、last())都基于这个新上下文计算。
注意:它不支持 break/continue,也不能嵌套修改变量(XSLT 变量不可变),本质是声明式处理,不是命令式循环。
常见写法示例
假设有如下 XML:
对应 XSLT 片段:
第
输出为两段 ,其中 position() 返回当前在 books/book 节点集中的序号(从 1 开始)。
替代 for-each 的更推荐方式
多数场景下,优先用 + 匹配模板,更符合 XSLT 的设计哲学,也更易维护和复用:
- 用
触发处理 - 单独定义
描述每本书怎么渲染 - 可配合
或灵活控制,无需硬编码逻辑到 for-each 内部 - 当需要条件过滤(如只显示价格 >50 的书),用
select="books/book[price > 50]"比在 for-each 里套 if 更简洁
容易踩的坑
-
select表达式写错路径(比如漏掉根节点或层级错误),导致 for-each 不执行——建议先用调试节点数量 - 在 for-each 内误用
./@id却忘了当前已是book节点,直接写@id就行 - 想按属性排序却没加
,for-each 本身不保证顺序(默认文档顺序,但不可依赖) - 混淆
position()和索引:它是当前 for-each 节点集里的位置,不是全局 XPath 索引










