xml - 为什么在第一个应用模板中没有选择

标签 xml xslt

我试图理解 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/

相关文章:

xslt - 如何使用xslt解析另一个xml的CDATA中的xml?

java - Android 菜单项 onclick

xml - 如何使用 Perl 中基于事件的解析器为海量数据构建 xml 树?

xml - XSL 和 XPATH 问题匹配

xslt - 图像上的文档最大宽度? (xml :fo)

xml - 为什么我的图像没有显示在 XSL-FO 中?

xslt - XSL 模板匹配语法

xml - 在初始创建后将元素添加/插入到 Groovy MarkupBuilder 对象中

xml - preceding-sibling [1] 不是最后一个

xml - 错误: The processing instruction target matching “[xX][mM][lL]” is not allowed