我试图理解 apply-templates
但我不明白为什么我不在这里的 apply-templates
中写任何 select="nodename": (我想到了我的 CD 收藏下的第一个应用模板)
输入文档的片段:
<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
<cd>
<title>Greatest Hits</title>
<artist>Dolly Parton</artist>
<country>USA</country>
<company>RCA</company>
<price>9.90</price>
<year>1982</year>
</cd>
XSLT:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="cd">
<p>
<xsl:apply-templates select="title"/>
<xsl:apply-templates select="artist"/>
</p>
</xsl:template>
<xsl:template match="title">
Title: <span style="color:#ff0000">
<xsl:value-of select="."/></span>
<br />
</xsl:template>
<xsl:template match="artist">
Artist: <span style="color:#00ff00">
<xsl:value-of select="."/></span>
<br />
</xsl:template>
</xsl:stylesheet>
摘自 w3schools 教程。它如何理解应该选择哪个模板?
最佳答案
根据规范:
In the absence of a select attribute, the xsl:apply-templates instruction processes all of the children of the current node, including text nodes.
apply-templates
没有 XPath 选择,按照处理器在编译期间构建的 XML TreeView 的层次结构应用模板,除非您明确驱动模板(就像您为 title 所做的那样)
和 艺术家
)。
您可能还想想想如何 built-in template rules工作。这些规则在幕后运行,并允许在没有成功模式匹配的情况下继续递归过程。
因此,如果您省略根 /
的模板匹配,您的模板无论如何都会被执行,这要归功于内置规则。
我觉得处理顺序应该是这样的:
- 模板与根匹配,
xsl:apply-templates
告诉处理器将模板应用到catalog
元素(在它被调用的地方)。 - 没有找到
catalog
的匹配模板,因此内置规则允许继续处理其他后代元素(catalog
),直到新模板具有成功的模式找到匹配项 (cd
)
内置规则在幕后运行,您必须始终认为您的转换是由您的模板以及一些额外的隐藏(但有效)模板组成的:
<xsl:template match="*|/">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="text()|@*">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="processing-instruction()|comment()"/>
在您的特定情况下,上述三个模板中的前一个模板负责将模板应用于 cd
元素。
每次您编写显式模板时,这些内置模板都会被覆盖。
示例
您可以通过替换获得相同的内容:
<xsl:template match="cd">
<p>
<xsl:apply-templates select="title"/>
<xsl:apply-templates select="artist"/>
</p>
</xsl:template>
与:
<xsl:template match="country|company|price|year"/>
<xsl:template match="cd">
<p>
<xsl:apply-templates />
</p>
</xsl:template>
关于根,在你的情况下,你也可以通过替换获得相同的:
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
与
<xsl:template match="/catalog">
<html>
<body>
<h2>My CD Collection</h2>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
还是:
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<xsl:apply-templates select="catalog"/>
</body>
</html>
</xsl:template>
还是:
<xsl:template match="catalog">
<html>
<body>
<h2>My CD Collection</h2>
<xsl:apply-templates />
</body>
</html>
</xsl:template>
关于xml - 为什么在第一个应用模板中没有选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6324637/