ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

XSLT:apply-templates 深入详解

XSLT:apply-templates 深入详解 1. 引言XSLT 与模板驱动的转换模型XSLTExtensible Stylesheet Language Transformations是处理 XML 文档的经典语言它采用声明式的模板驱动模型。整个转换的核心就是“模板规则”template rules而将控制权交给这些规则的关键指令就是xsl:apply-templates。本文将围绕这一核心指令展开通过大量可运行的代码实例带你彻底掌握它的用法和最佳实践。2. xsl:apply-templates 的核心概念xsl:apply-templates 的作用是告诉 XSLT 处理器“去为当前节点的子节点或指定节点集寻找匹配的模板规则并应用它们”。它本身不直接产生输出而是推动模板规则的选择与执行是整个转换流程的“调度器”。它的常用属性有select指定要处理的节点集XPath 表达式。默认值为node()即当前节点所有子节点。mode限定只在具有相同 mode 的模板中进行匹配用于对同一节点进行多种不同处理。3. 基础示例最简单的“复制并转换”我们从一个简单的例子开始将一段 XML 数据转换为 HTML 列表。3.1 输入 XML?xml version1.0 encodingUTF-8? books book title深入理解 XSLT/title author张三/author /book book titleXML 实战指南/title author李四/author /book /books3.2 XSLT 样式表?xml version1.0 encodingUTF-8? xsl:stylesheet version1.0 xmlns:xslhttp://www.w3.org/1999/XSL/Transform !-- 根模板 -- xsl:template match/ html body h2图书列表/h2 ul xsl:apply-templates selectbooks/book / /ul /body /html /xsl:template !-- 处理每个 book 节点 -- xsl:template matchbook li xsl:value-of selecttitle / —— xsl:value-of selectauthor / /li /xsl:template /xsl:stylesheet关键点根模板中通过xsl:apply-templates selectbooks/book /选择所有book元素处理器随后找到matchbook的模板并进行处理。输出如下html body h2图书列表/h2 ul li深入理解 XSLT —— 张三/li liXML 实战指南 —— 李四/li /ul /body /html4. 利用 select 属性进行有选择的处理默认的selectnode()会处理所有子节点包括文本节点、注释等大多数时候我们需要通过 XPath 表达式精准选择节点。假设我们只输出书名中包含“XML”的图书xsl:apply-templates selectbooks/book[contains(title, XML)] /或者只处理前两本书xsl:apply-templates selectbooks/book[position() lt; 2] /select 表达式非常灵活可以结合所有 XPath 函数让你在应用模板前完成过滤、排序和计算。5. 使用 mode 实现同一节点的多种呈现有时候我们需要对同一份数据进行不同的转换例如生成 HTML 页面和纯文本摘要。这时可以为同一个节点定义多个模板用mode加以区分。xsl:stylesheet version1.0 xmlns:xslhttp://www.w3.org/1999/XSL/Transform xsl:template match/ html body h2摘要模式/h2 ul xsl:apply-templates selectbooks/book modebrief / /ul h2详细模式/h2 xsl:apply-templates selectbooks/book modefull / /body /html /xsl:template !-- 摘要模板 -- xsl:template matchbook modebrief lixsl:value-of selecttitle //li /xsl:template !-- 详细模板 -- xsl:template matchbook modefull div h3xsl:value-of selecttitle //h3 p作者xsl:value-of selectauthor //p /div /xsl:template /xsl:stylesheet通过modebrief和modefull我们在同一文档中实现了两种不同的展示风格互不干扰。6. 排序与 xsl:sort 结合使用xsl:apply-templates 内部可以包含一个或多个xsl:sort元素用于指定处理节点的顺序。排序在模板应用之前完成不会修改输出顺序之外的内容。按作者姓名字母顺序输出图书xsl:apply-templates selectbooks/book xsl:sort selectauthor / /xsl:apply-templates也可以进行多级排序比如先按作者再按书名xsl:apply-templates selectbooks/book xsl:sort selectauthor / xsl:sort selecttitle / /xsl:apply-templates还可以控制排序数据类型和顺序xsl:apply-templates selectbooks/book xsl:sort selectprice>xsl:template match/ ul xsl:apply-templates selectbooks/book xsl:sort selectauthor / xsl:with-param nameseq selectposition() / /xsl:apply-templates /ul /xsl:template xsl:template matchbook xsl:param nameseq / li xsl:value-of select$seq /. xsl:value-of selecttitle / /li /xsl:template注意selectposition()的值在排序之后计算因此可以真实反映排序后的位置。参数传递使得模板的复用性大大提高你可以用同一个matchbook模板输出不同的附加信息。8. 命名模板 vs. apply-templates何时用谁XSLT 中有两种调用模板的方式apply-templates和call-template。前者是“让处理器自动寻找匹配的模板”后者是“显式调用一个命名模板”。apply-templates基于节点内容类型、上下文自动匹配适合处理结构化数据更符合声明式编程风格。call-template像函数调用适合封装可复用的逻辑例如生成格式化字符串不依赖当前节点。一个简单的对比!-- 使用 apply-templates -- xsl:apply-templates selectmessage / xsl:template matchmessage pxsl:value-of select. //p /xsl:template !-- 使用 call-template -- xsl:call-template nameprint-message xsl:with-param namemsg selectmessage / /xsl:call-template xsl:template nameprint-message xsl:param namemsg / pxsl:value-of select$msg //p /xsl:template在面向文档的转换中apply-templates往往是更好的选择而在构建工具类函数时call-template更直观。9. 常见陷阱与调试技巧忘记默认选择子节点如果没有selectapply-templates会处理所有子节点包括空白文本节点可能导致意外的空白输出。模板优先级混淆如果有多个模板匹配同一节点XSLT 会按照内置优先级规则选择必要时可使用priority属性显式指定。在排序中使用position()在xsl:sort的select中使用position()是排序前的位置通常不是你要的建议在排序后的模板中通过参数获取位置。调试输出可以在模板中插入xsl:message或生成临时 HTML 注释来观察执行流程。10. 实战将 RSS 提要转换为 HTML 摘要页面最后我们看一个将 RSS 2.0 订阅源转换为可读 HTML 的完整例子综合运用了 apply-templates、select、sort 和参数传递。?xml version1.0 encodingUTF-8? xsl:stylesheet version1.0 xmlns:xslhttp://www.w3.org/1999/XSL/Transform xsl:template match/ html headtitleRSS Digest/title/head body h1xsl:value-of selectrss/channel/title //h1 xsl:apply-templates selectrss/channel/item xsl:sort selectpubDate orderdescending / xsl:with-param nameindex selectposition() / /xsl:apply-templates /body /html /xsl:template xsl:template matchitem xsl:param nameindex / div classentry h2xsl:value-of select$index /. xsl:value-of selecttitle //h2 pemxsl:value-of selectpubDate //em/p pxsl:value-of selectdescription disable-output-escapingyes //p pa href{link}阅读原文/a/p /div /xsl:template /xsl:stylesheet这个例子展示了 apply-templates 在真实场景中的强大威力只需少量声明式代码就能完成排序、编号和结构化输出。11. 总结xsl:apply-templates 是 XSLT 编程思想的核心体现将关注点转向“什么数据应该被处理”以及“用什么规则处理”而不是“如何一步步生成结果”。熟练掌握 select、mode、sort 和参数传递能让你编写出更清晰、更灵活、更易维护的样式表。希望本文的代码实例能帮助你在实际项目中用好这一指令。
返回列表