XSLT模板如何编写?(编写.模板.XSLT...)

wufei123 发布于 2025-09-11 阅读(2)
<blockquote>XSLT模板的核心是通过匹配(match)和应用(apply-templates)机制,利用xsl:template、xsl:value-of、xsl:for-each、xsl:if等元素,结合XPath定位节点,实现XML到HTML或其他格式的声明式转换。</blockquote> <p><img src="https://img.php.cn/upload/article/001/221/864/175721520222566.jpg" alt="xslt模板如何编写?"></p> <p>编写XSLT模板,本质上是定义一套规则,告诉<a style="color:#f60; text-decoration:underline;" title="处理器" href="https://www.php.cn/zt/16030.html" target="_blank">处理器</a>如何将XML文档从一种结构转换成另一种,通常是HTML或其他XML格式。这就像给一个厨师菜谱,详细说明每种食材(XML节点)如何处理、组合,最终呈现一道新菜(转换后的文档)。核心在于通过匹配(<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">match</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>)特定的XML节点,然后定义这些节点应该如何被转换和输出。它不是编程,更像是一种声明式的映射,你声明想要什么结果,而不是一步步地告诉机器怎么做。</p> <p>XSLT模板的编写,从我的经验来看,总是围绕着“匹配”与““应用”这两个核心概念展开。你需要先有一个XML源文档,然后用XSLT来描述你希望它最终变成什么样子。最基础的结构就是<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:stylesheet</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>元素,里面包含了各种<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:template</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>规则。每个<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:template</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>都有一个<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">match</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>属性,用来指定它要处理哪个XML节点。</p> <p>举个例子,假设我们有一个简单的XML数据:</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:xml;toolbar:false;'><books> <book id="1"> <title>XSLT权威指南</title> <author>某某</author> <price>59.00</price> </book> <book id="2"> <title>XML入门</title> <author>张三</author> <price>45.50</price> </book> </books></pre><div class="contentsignin"> </div></div><p>我们想把它转换成一个HTML列表。那么,我们的XSLT模板可能会这样起步:</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:xml;toolbar:false;'><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 根模板:匹配整个文档的根节点 --> <xsl:template match="/"> <html> <head> <title>我的书单</title> </head> <body> <h1>书籍列表</h1> <ul> <!-- 应用模板到所有的book节点 --> <xsl:apply-templates select="books/book"/> </ul> </body> </html> </xsl:template> <!-- book节点的模板:定义每个book如何显示 --> <xsl:template match="book"> <li> <span style="font-weight: bold;"><xsl:value-of select="title"/></span> by <xsl:value-of select="author"/> (<xsl:value-of select="price"/>元) </li> </xsl:template> </xsl:stylesheet></pre><div class="contentsignin"> </div></div><p>在这个例子里,<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:template match="/"</pre><div class="contentsignin"> </div></div> 处理整个XML文档的根,构建了HTML的基本骨架。然后,它用<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:apply-templates select="books/book"</pre><div class="contentsignin"> </div></div> 来告诉处理器,“现在去找到所有<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">books</pre><div class="contentsignin"> </div></div>下的<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">book</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>节点,并为它们应用合适的模板”。接着,<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:template match="book"</pre><div class="contentsignin"> </div></div> 就被激活了,它定义了每个<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">book</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>节点应该如何转换成一个<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;"><li></pre><div class="contentsignin"> </div></div>元素,并提取了书名、作者和价格。这是一种非常常见的模式,通过递归应用模板来处理XML树结构。</p> <h3>XSLT模板的核心结构与工作原理是什么?</h3> <p>XSLT模板的核心结构,说白了,就是由一个根元素<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:stylesheet</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>(或者<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:transform</pre><div class="contentsignin"> </div></div>,它们是同义的)包裹着一系列的<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:template</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>元素。这个<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:stylesheet</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>元素通常会带一个<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">version</pre><div class="contentsignin"> </div></div>属性,比如<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">version="1.0"</pre><div class="contentsignin"> </div></div>或<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">version="2.0"</pre><div class="contentsignin"> </div></div>,以及一个XML命名空间声明<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xmlns:xsl="http://www.w3.org/1999/XSL/Transform"</pre><div class="contentsignin"> </div></div>,这告诉处理器,这里面定义的都是XSLT指令。</p> <p>每个<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:template</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>是真正定义转换规则的地方。它最关键的属性是<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">match</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>,这个属性的值是一个XPath表达式。XPath是XSLT的伙伴,它就像一个地图,用来精确地定位XML文档中的特定节点或节点集。比如<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">match="/"</pre><div class="contentsignin"> </div></div>匹配文档的根节点,<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">match="book"</pre><div class="contentsignin"> </div></div>匹配所有名为<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">book</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>的元素,<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">match="book[@category='fiction']"</pre><div class="contentsignin"> </div></div>则匹配所有<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">category</pre><div class="contentsignin"> </div></div>属性为<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">fiction</pre><div class="contentsignin"> </div></div>的<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">book</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>元素。</p> <p>当XSLT处理器开始工作时,它会从XML源文档的根节点开始,遍历整个文档树。每遇到一个节点,它就会尝试找到一个与之<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">match</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>属性匹配的<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:template</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>。如果找到了,就会执行那个模板内部的指令。如果一个节点没有明确匹配的模板,XSLT有一个内置的默认模板,通常是复制文本内容并递归处理子节点。</p> <p>理解这种“匹配-应用”的机制非常重要。<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:apply-templates</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>指令是驱动这种递归转换的关键。它会选择一组节点,并为这些节点寻找并应用最合适的模板。如果没有<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">select</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>属性,它会默认处理当前节点的所有子节点。这种机制使得XSLT非常适合处理层级结构化的数据,你可以为不同层级的节点定义不同的转换规则,而不需要手动编写复杂的循环和条件判断。</p> <h3>XSLT如何实现数据提取、循环与条件逻辑?</h3> <p>在XSLT中,数据提取、循环和条件逻辑是构建复杂转换的核心<a style="color:#f60; text-decoration:underline;" title="工具" href="https://www.php.cn/zt/16887.html" target="_blank">工具</a>。它们让模板变得“活”起来,能够根据数据内容动态生成输出。</p> <div class="aritcle_card"> <a class="aritcle_card_img" href="/ai/pia"><img src="https://img.php.cn/upload/ai_manual/000/000/000/175680367646107.png" alt="PIA"></a> <div class="aritcle_card_info"> <a href="/ai/pia">PIA</a> <p>全面的AI聚合平台,一站式访问所有顶级AI模型</p> <div class=""> <img src="/static/images/card_xiazai.png" alt="PIA"><span>226</span> </div> </div> <a href="/ai/pia" class="aritcle_card_btn"> <span>查看详情</span> <img src="/static/images/cardxiayige-3.png" alt="PIA"></a> </div> <p><strong>数据提取</strong>:最常用的就是<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:value-of</pre><div class="contentsignin"> </div></div>元素。它有一个<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">select</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>属性,同样接受一个XPath表达式。这个表达式会从当前上下文节点(也就是当前正在处理的那个XML节点)开始,选择一个节点或一个属性的值,然后将其文本内容插入到输出中。比如,在<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">book</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>模板里,<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:value-of select="title"</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>会提取当前<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">book</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>元素下的<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">title</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>子元素的文本内容。如果想获取属性值,就用<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">@</pre><div class="contentsignin"> </div></div>符号,比如<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:value-of select="@id"</pre><div class="contentsignin"> </div></div>会提取<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">book</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>元素的<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">id</pre><div class="contentsignin"> </div></div>属性值。这非常直接,但要注意,它只会提取第一个匹配节点的文本内容,如果你期望获取多个,那通常需要结合循环。</p> <p><strong>循环</strong>:<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:for-each</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>是XSLT中实现循环的利器。它的<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">select</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>属性也接受一个XPath表达式,用于选择一组节点。然后,<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:for-each</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>会遍历这组节点中的每一个,并为每个节点执行其内部定义的指令。在每次迭代中,当前节点会变成<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:for-each</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>所处理的那个节点。这对于生成列表、表格行或者重复的HTML结构非常有用。</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:xml;toolbar:false;'><!-- 示例:使用xsl:for-each遍历所有book并显示 --> <xsl:template match="books"> <ul> <xsl:for-each select="book"> <li> 书名: <xsl:value-of select="title"/>, 作者: <xsl:value-of select="author"/> </li> </xsl:for-each> </ul> </xsl:template></pre><div class="contentsignin"> </div></div><p>相比于<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:apply-templates</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>,<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:for-each</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>更像是传统的编程循环,它会强制按照<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">select</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>表达式选择的顺序和方式来处理节点,而<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:apply-templates</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>则会根据匹配规则和优先级来选择最合适的模板。在某些场景下,<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:for-each</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>更直观,尤其是在你不需要为子节点定义复杂模板,只是想简单遍历并输出它们的内容时。</p> <p><strong>条件逻辑</strong>:XSLT提供了<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:if</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>和<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:choose</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>两种方式来实现条件判断。</p> <ul> <li><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:if</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>:它有一个<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">test</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>属性,接受一个XPath表达式,该表达式的结果会被转换为一个布尔值。如果为<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">true</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>,<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:if</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>内部的内容就会被处理并输出;否则,什么都不会发生。<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:xml;toolbar:false;'><!-- 示例:如果价格大于50,则加粗显示 --> <xsl:template match="book"> <li> <xsl:value-of select="title"/> - <xsl:if test="price > 50"> <span style="font-weight: bold;">高价书!</span> </xsl:if> 价格: <xsl:value-of select="price"/> </li> </xsl:template></pre><div class="contentsignin"> </div></div></li> <li><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:choose</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>:这相当于其他语言中的<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">if-else if-else</pre><div class="contentsignin"> </div></div>结构,可以处理多个互斥的条件。它包含一个或多个<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:when</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>子元素,每个<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:when</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>也有一个<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">test</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>属性。处理器会按顺序评估<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:when</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>的条件,第一个为<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">true</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>的<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:when</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>内部内容会被执行,然后跳出<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:choose</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>。如果所有<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:when</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>的条件都为<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">false</pre><div class="contentsignin"> </div></div>,那么可选的<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:otherwise</pre><div class="contentsignin"> </div></div>子元素(如果有的话)内部内容就会被执行。<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:xml;toolbar:false;'><!-- 示例:根据价格区间显示不同信息 --> <xsl:template match="book"> <li> <xsl:value-of select="title"/> - <xsl:choose> <xsl:when test="price > 80"> <span style="color: red;">非常昂贵!</span> </xsl:when> <xsl:when test="price > 50"> <span style="color: orange;">价格偏高。</span> </xsl:when> <xsl:otherwise> <span style="color: green;">经济实惠。</span> </xsl:otherwise> </xsl:choose> 价格: <xsl:value-of select="price"/> </li> </xsl:template></pre><div class="contentsignin"> </div></div><p>注意,在XML中,<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">></pre><div class="contentsignin"> </div></div>和<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;"><</pre><div class="contentsignin"> </div></div>是特殊字符,通常需要用实体引用<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">></pre><div class="contentsignin"> </div></div>和<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;"><</pre><div class="contentsignin"> </div></div>来表示。</p> </li> </ul> <h3>XSLT模板编写中有哪些常见陷阱与优化技巧?</h3> <p>说实话,XSLT模板编写过程中,有些地方初学者很容易踩坑,而一些小技巧又能显著提升模板的效率和可维护性。</p> <p><strong>常见陷阱:</strong></p> <ol> <li> <strong>上下文节点(Context Node)的迷失</strong>:这是最常见的问题。XSLT的操作总是围绕着一个“当前上下文节点”进行的。当你使用<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:value-of select="title"</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>时,<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">title</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>是相对于当前节点而言的。但在<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:for-each</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>内部,上下文节点会变成<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:for-each</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>正在处理的那个节点。如果在这个循环里你又想访问循环外部的某个节点,比如根节点下的某个全局配置,直接写<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">title</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>或者<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">../otherNode</pre><div class="contentsignin"> </div></div>可能就不对了,你需要使用绝对路径(如<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">/books/config/setting</pre><div class="contentsignin"> </div></div>)或者通过变量来保存。</li> <li> <strong>命名空间(Namespaces)问题</strong>:XML和XSLT都大量使用命名空间。如果你的源XML文档使用了命名空间,而你的XSLT模板没有正确声明或使用这些命名空间,那么XPath表达式就无法匹配到节点。比如,如果XML是<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;"><doc:book xmlns:doc="http://example.com/books"></pre><div class="contentsignin"> </div></div>,你的XSLT也需要声明<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xmlns:doc="http://example.com/books"</pre><div class="contentsignin"> </div></div>,然后用<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">doc:book</pre><div class="contentsignin"> </div></div>来匹配。忘记这一点,你会发现XPath怎么都匹配不上。</li> <li> <strong><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:apply-templates</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>与<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:for-each</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>的选择</strong>:虽然它们都能实现循环,但语义和性能有时有差异。<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:apply-templates</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>更倾向于“推”模型,它让处理器根据匹配规则自动选择最合适的模板,这在处理复杂、多态的XML结构时非常强大和灵活。而<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:for-each</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>更像“拉”模型,你明确指定要遍历哪些节点,然后对它们做统一处理。滥用<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:for-each</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>可能会导致模板不够模块化,难以维护,并且在某些XSLT处理器上可能效率不如<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:apply-templates</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>。</li> <li> <strong>XPath表达式的效率</strong>:复杂的XPath表达式,尤其是那些需要遍历大量节点的,可能会影响性能。比如<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">//title</pre><div class="contentsignin"> </div></div>(选择文档中所有<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">title</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>元素)通常比<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">books/book/title</pre><div class="contentsignin"> </div></div>效率低,因为它需要搜索整个文档树。尽量使用更精确的路径。</li> </ol> <p><strong>优化技巧:</strong></p> <ol> <li> <strong>模块化模板</strong>:将大的转换任务分解成小的、可重用的<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:template</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>。这不仅提高了可读性,也方便维护。一个模板只做一件事,匹配一个特定类型的节点,并定义它的输出。</li> <li> <strong>使用<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:variable</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>和<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:param</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div></strong>:<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:variable</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>用于在模板内部存储计算结果或频繁使用的值,避免重复计算或重复写长XPath。<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:param</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>则允许你在调用模板时传入参数,增加模板的灵活性和复用性。</li> <li> <strong>模式匹配的优先级</strong>:了解XSLT处理器如何解决多个模板匹配同一个节点时的冲突(优先级规则),这有助于你写出更精确的模板。通常,更具体的匹配模式(如<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">book[@id='1']</pre><div class="contentsignin"> </div></div>)会比一般模式(如<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">book</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>)有更高的优先级。</li> <li> <strong>善用内置模板</strong>:XSLT有一些默认行为,比如默认会复制文本节点。在某些情况下,你可以利用这些默认行为,只定义需要特殊处理的节点模板,减少模板代码量。</li> <li> <strong>输出方法(<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:output</pre><div class="contentsignin"> </div></div>)</strong>:在<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:stylesheet</pre><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div><div class="contentsignin"> </div></div>的顶部,使用<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:output method="html"</pre><div class="contentsignin"> </div></div>、<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">method="xml"</pre><div class="contentsignin"> </div></div>或<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">method="text"</pre><div class="contentsignin"> </div></div>来指定输出类型。这会影响XSLT处理器如何<a style="color:#f60; text-decoration:underline;" title="格式化输出" href="https://www.php.cn/zt/37682.html" target="_blank">格式化输出</a>,比如是否添加XML声明、是否自闭合空标签等。</li> <li> <strong>调试策略</strong>:XSLT调试有时确实有点棘手,因为它是声明式的。我通常会通过插入临时的<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;">xsl:message</pre><div class="contentsignin"> </div></div>来输出变量值或当前上下文路径,或者直接在输出中加入调试信息,比如<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false;"><!-- Debug: Current node is <xsl:value-of select="name()"/> --></pre><div class="contentsignin"> </div></div>,这样可以帮助我理解模板的执行流程和数据状态。</li> </ol> <p>XSLT是一个非常强大的工具,但它的思维方式与命令式编程有所不同。一旦你掌握了它的核心概念,比如匹配、上下文、以及声明式转换的思想,你就会发现它在处理XML数据转换时是多么优雅和高效。</p>

以上就是XSLT模板如何编写?的详细内容,更多请关注知识资源分享宝库其它相关文章!

相关标签: html node go 处理器 app 工具 格式化输出 red html if for 命名空间 多态 select xml 递归 循环 transform li http 大家都在看: XSLT如何调用模板? XML如何表示神经网络模型? XSLT模板如何编写? SOAP服务文档模板?WSDL编写指南? SOAP服务测试数据?如何模拟请求?

XSLT模板如何编写?(编写.模板.XSLT...)

标签:  编写 模板 XSLT 

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。