XSLT怎么递归处理树形结构的XML

XSLT递归处理树形XML的核心是配合匹配子节点的模板实现自动向下递归;通过match属性定义模板、select指定子节点、mode或条件判断区分层级、with-param传递上下文,并确保select明确及strip-space防干扰。

XSLT 递归处理树形结构 XML,核心是用 配合匹配子节点的模板,让处理器自动“向下走”,遇到子元素就再调用自己——这本质上就是递归。

matchapply-templates 构建递归入口

树形 XML 通常有嵌套的同名元素(如 ),XSLT 不需要写 forwhile,而是靠模板匹配驱动递归:

  • 定义一个模板匹配 node 元素(或任意父级容器)
  • 在该模板内部,用 显式处理所有直接子 node
  • 因为子 node 也满足 match="node",所以会再次进入同一模板——递归发生

控制递归深度和边界:用 mode 或条件隔离不同层级

有时根节点和叶子节点要渲染不同内容,光靠匹配不够。可用以下方式区分:

  • mode 属性:比如 ,再写单独的 match="node" mode="child" 模板
  • 判断是否为叶子节点(无子 node
  • 判断是否非根(有父级 node

传递上下文信息:用 带深度或路径

纯模板递归不带参数,但常需知道当前层级、祖先路径或编号。这时要用命名模板 + 主动递归:

  • 把逻辑封装进
  • 首次调用时传入初始参数:
  • 模板内处理完本层后,对每个子节点再次 ,并传入 $depth + 1

避免无限递归:确保有明确终止条件

XSLT 不会栈溢出,但若模板总匹配自己又没限制子集,可能重复处理或漏数据:

  • 始终用 select="xxx" 明确指定下一层要处理的子节点(如 select="child::node"),别用 select="*" 意外匹配到文本/注释
  • 如果 XML 有混合内容(文本+元素),加 清除空白文本节点干扰
  • 空模板忽略无关文本,防止默认规则介入

基本上就这些。XSLT 的递归不是编程语言里的函数调用,而是声明式“匹配→应用→再匹配”的自然展开。写熟了,比手写 for 循环还干净。