XSLT  xsl:apply-templates元素

XSLT 中 <xsl:apply-templates> 元素详解

<xsl:apply-templates> 是 XSLT 中最核心、最常用的指令之一,它体现了 XSLT “基于模板规则(template rules)”的声明式编程思想。

基本语法

<xsl:apply-templates 
    select="表达式" 
    mode="模式名称">
    <xsl:sort />          <!-- 可选的排序 -->
    <xsl:with-param />    <!-- 向被调用的模板传递参数 -->
</xsl:apply-templates>

主要属性

属性是否必须说明示例
select指定要处理哪些节点。如果省略,默认处理当前节点的全部子节点(按文档顺序)select="book"select="//item"
mode用于区分同一节点在不同场景下使用不同的模板,防止模板无限递归或冲突mode="toc"mode="content"

工作原理(重点)

  1. XSLT 处理器在遇到 <xsl:apply-templates> 时,会根据当前上下文节点去查找最匹配、最优先<xsl:template match="...">
  2. 查找顺序遵循 XPath 的匹配规则和 XSLT 的导入优先级(import precedence)模板优先级(priority)
  3. 找到匹配的模板后,将 select 选出的节点逐个作为当前节点传入该模板执行。
  4. 如果有 mode 属性,只会匹配同样带有相同 mode 的模板。

常见用法示例

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <!-- 默认处理所有书 -->
  <xsl:template match="book">
    <div class="book">
      <h2><xsl:value-of select="title"/></h2>
      <xsl:apply-templates select="author | year"/>   <!-- 只处理 author 和 year -->
    </div>
  </xsl:template>

  <!-- 单独处理作者 -->
  <xsl:template match="author">
    <p>作者:<xsl:value-of select="."/></p>
  </xsl:template>

  <!-- 在目录模式下只输出标题 -->
  <xsl:template match="book" mode="toc">
    <li><xsl:value-of select="title"/></li>
  </xsl:template>

  <!-- 主模板 -->
  <xsl:template match="/library">
    <html>
      <body>
        <h1>目录</h1>
        <ul>
          <xsl:apply-templates select="book" mode="toc"/>   <!-- 使用 toc 模式 -->
        </ul>

        <h1>详细内容</h1>
        <xsl:apply-templates/>   <!-- 省略 select,默认处理所有子节点(即所有 book) -->
      </body>
    </html>
  </xsl:template>

</xsl:stylesheet>

<xsl:call-template> 的区别(常考点)

特性<xsl:apply-templates><xsl:call-template>
调用方式根据节点动态匹配模板直接按名字调用指定模板
传入节点会把选中的节点逐个作为当前节点传入不会改变当前节点
是否支持多态(同一节点不同处理)支持(配合 mode)不支持
是否需要参数传递通常不需要(节点本身就是上下文)经常需要用 <xsl:with-param> 传参
典型场景遍历、递归、内容驱动的转换抽取公共代码块、函数式调用

常见的“陷阱”和最佳实践

  1. 忘记写匹配文本节点的模板
    默认情况下,文本节点也会被 <xsl:apply-templates/> 处理,如果没有匹配模板,就会直接输出(常导致多余空格)。
    解决方法:
   <xsl:template match="text()"/>  <!-- 抑制所有纯文本输出 -->
   或
   <xsl:template match="text()[normalize-space(.)='']"/> <!-- 只抑制空白文本 -->
  1. 无限递归
    常见于写了 <xsl:template match="item"><xsl:apply-templates/></xsl:template> 却没有更具体的模板,导致一直匹配自己。
    mode 或更精确的 match 表达式避免。
  2. 性能问题
    select="//item" 这种全文档搜索很慢,尽量使用相对路径或索引。
  3. 排序
    可以在 <xsl:apply-templates> 内部使用 <xsl:sort>
   <xsl:apply-templates select="book">
     <xsl:sort select="year" data-type="number" order="descending"/>
     <xsl:sort select="title"/>
   </xsl:apply-templates>

总结一句话

<xsl:apply-templates> 是 XSLT 的“灵魂”,它让转换过程由数据驱动(push 风格 → pull 风格),而不是硬编码的顺序处理,是实现“一次编写,多种输出格式”的关键。

如果你有具体的转换场景需要用 <xsl:apply-templates> 实现,可以贴出 XML 和期望的输出,我可以帮你写出完整样式表。

文章已创建 2783

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部