XSLT模板应用顺序由导入优先级、模式特异性、priority属性和文档顺序共同决定,其中导入的样式表优先级最低,模式越具体优先级越高,priority值越大优先级越高,最后通过mode实现多上下文独立匹配。
XSLT处理模板应用顺序,核心在于一套明确的优先级规则。它不是随机的,而是基于模板匹配模式的“特异性”(specificity)、开发者显式设置的
priority
import
要控制XSLT模板的应用顺序,我们需要理解并运用以下几个关键机制:
首先是模式的特异性。这是最基础也最强大的规则。XSLT处理器会优先选择那些对当前节点匹配模式最“具体”的模板。例如,
match="elementName"
match="*"
match="parent/child"
match="child"
其次是priority
xsl:template
priority
priority
<xsl:template match="book" priority="10"> <!-- 这个模板会优先处理book元素 --> <p>高优先级图书: <xsl:value-of select="title"/></p> </xsl:template> <xsl:template match="book"> <!-- 默认优先级,低于上面的模板 --> <p>普通图书: <xsl:value-of select="title"/></p> </xsl:template>
再来是import
include
xsl:import
xsl:include
<!-- main.xsl --> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:import href="imported.xsl"/> <xsl:template match="data"> <!-- 这个模板会优先于imported.xsl中匹配data的模板 --> <main-data><xsl:apply-templates/></main-data> </xsl:template> </xsl:stylesheet> <!-- imported.xsl --> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="data"> <imported-data><xsl:apply-templates/></imported-data> </xsl:template> </xsl:stylesheet>
最后是mode
mode
mode
xsl:apply-templates
mode
mode
<xsl:template match="item" mode="summary"> <!-- 在summary模式下处理item --> <li>摘要: <xsl:value-of select="title"/></li> </xsl:template> <xsl:template match="item" mode="detail"> <!-- 在detail模式下处理item --> <div>详情: <xsl:value-of select="description"/></div> </xsl:template> <!-- 调用时指定模式 --> <xsl:apply-templates select="items/item" mode="summary"/> <xsl:apply-templates select="items/item" mode="detail"/>
XSLT模板匹配的优先级,其实是一个多层级的决策过程。它不是简单的“谁写在前面谁优先”,而是有一套清晰的、可预测的算法。我个人在调试一些复杂转换时,常常会因为忽略了某个层级而感到困惑,但一旦理解了这套规则,XSLT的确定性就变得非常可靠。
最优先考虑的是导入优先级。如果你通过
xsl:import
其次是模式的特异性。这是最常见的冲突解决机制。XSLT会计算每个匹配模式的“特异性值”。例如,
id('foo')
elementName[attribute='value']
*
node()
book
*
chapter[title='Intro']
chapter
然后是priority
priority
最后,如果所有上述规则都无法区分出唯一的模板(这在实践中很少发生,除非是完全相同的模板定义),XSLT规范规定会选择在样式表中“最后出现”的那个模板。不过,依赖这个规则通常不是一个好习惯,因为它可能会导致难以维护和理解的代码。更好的做法是使用
priority
mode
mode
mode
没有
mode
xsl:if
mode
例如,假设我们有一个XML,包含书籍信息:
<catalog> <book id="b1"> <title>XSLT Cookbook</title> <author>John Doe</author> <price>39.99</price> <description>A comprehensive guide to XSLT.</description> </book> <book id="b2"> <title>XML Basics</title> <author>Jane Smith</author> <price>29.99</price> <description>Learn the fundamentals of XML.</description> </book> </catalog>
现在我们想生成一个图书列表(只显示标题和作者),以及一个单独的图书详情页面。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" indent="yes"/> <xsl:template match="/"> <html> <head><title>图书列表与详情</title></head> <body> <h1>图书列表</h1> <ul> <xsl:apply-templates select="catalog/book" mode="list"/> </ul> <h1>图书详情</h1> <xsl:apply-templates select="catalog/book" mode="detail"/> </body> </html> </xsl:template> <!-- 列表模式的模板 --> <xsl:template match="book" mode="list"> <li> <xsl:value-of select="title"/> by <xsl:value-of select="author"/> </li> </xsl:template> <!-- 详情模式的模板 --> <xsl:template match="book" mode="detail"> <div class="book-detail"> <h2><xsl:value-of select="title"/></h2> <p>作者: <xsl:value-of select="author"/></p> <p>价格: $<xsl:value-of select="price"/></p> <p>描述: <xsl:value-of select="description"/></p> </div> </xsl:template> <!-- 默认模式下不处理book元素,避免意外输出 --> <xsl:template match="book"/> </xsl:stylesheet>
在这个例子中,
xsl:apply-templates
mode
mode="list"
book
mode="list"
mode="detail"
book
mode="detail"
XSLT在处理多个模板规则可能匹配同一个节点时的冲突解决机制,是其确定性和可靠性的基石。它并非随机选择,也不是简单地依赖定义顺序(除了最后那条作为tie-breaker的规则)。理解这个过程,对于编写健壮的XSLT代码至关重要。
当XSLT处理器遍历XML树并遇到一个节点时,它会检查所有定义的
xsl:template
match
这个过程遵循一个严格的优先级序列:
导入优先级:这是最重要的外部因素。如果一个模板是从一个被导入的样式表(通过
xsl:import
模式特异性:这是最核心的内部因素。XSLT会计算每个匹配模式的“特异性分值”。一个模式越具体,它的分值就越高,优先级也就越高。例如:
id('foo')
elementName[attribute='value']
elementName
*
parent/child
child
text()
comment()
node()
priority
priority
priority
文档顺序:这是一个“最后手段”。如果上述所有规则都无法区分出唯一的最佳匹配模板(这通常意味着你定义了两个完全相同的模板,或者它们在所有优先级规则上都恰好相等),XSLT规范规定会选择在样式表(或被包含的样式表)中“最后出现”的那个模板。我个人认为,依赖这条规则是不明智的,因为它会让代码变得难以理解和维护。更好的实践是,当遇到这种模糊情况时,使用
priority
了解这些规则后,当遇到意外的转换结果时,我通常会从特异性入手检查,看是否有更具体的模板“抢占”了优先级;然后检查
priority
import
以上就是XSLT如何控制模板应用顺序?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 //m.sbmmt.com/ All Rights Reserved | php.cn | 湘ICP备2023035733号