<apply-templates/> vs <apply-templates select="..."/> 在 XSLT 中

Tom*_*mmy 0 xslt apply-templates

查看地址下的 XSLT 代码http://www.w3schools.com/xml/tryxslt.asp?xmlfile=cdcatalog&xsltfile=cdcatalog_apply ... 下面你会找到这段代码的第一部分(也是我的问题的决定性部分) ):

<?xml version="1.0" encoding="UTF-8"?>
<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>
Run Code Online (Sandbox Code Playgroud)

如果您现在只更改行

<xsl:apply-templates/> 
Run Code Online (Sandbox Code Playgroud)

<xsl:apply-templates select="cd"/>
Run Code Online (Sandbox Code Playgroud)

转换不再起作用......(代码现在如下所示:)

<?xml version="1.0" encoding="UTF-8"?>
<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 select="cd"/>  <!--ONLY LINE OF CODE THAT WAS CHANGED-->
</body>
</html>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

我的问题是:为什么更改会破坏代码?在我看来,这两种情况的逻辑是一样的:

  1. 应用匹配“cd”的模板
  2. 内部模板“cd”应用其他两个模板(“标题”+“艺术家”)

更新:

整个xslt代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<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>
Run Code Online (Sandbox Code Playgroud)

这是xml的摘录:

<?xml version="1.0" encoding="UTF-8"?>
<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>
    ......
 </catalog>
Run Code Online (Sandbox Code Playgroud)

Tim*_*m C 5

W3C 学校没有告诉您的是关于 XSLT 的内置模板规则

当你这样做时,<xsl:apply-templates select="cd"/>你被定位在文档节点上,它是catalog元素的父元素。做select="cd"将不选择任何东西,因为它cdcatalog元素的子节点,而不是文档节点本身的子节点。只是catalog一个孩子。

(注意它catalog是 XML 的“根元素”。一个 XML 文档只能有一个根元素)。

但是,当您这样做时<xsl:apply-templates />,这相当于<xsl:apply-templates select="node()" />which 将选择catalog元素。这是内置模板发挥作用的地方。XSLT 中没有匹配的模板catalog,因此使用内置模板。

<xsl:template match="*|/">
   <xsl:apply-templates/>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

(这里*匹配任何元素)。因此,这个内置模板将选择 的子节点catalog,从而匹配 XSLT 中的其他模板。

请注意,在您的第二个示例中,您可以将模板匹配更改为此...

<xsl:template match="/*">
Run Code Online (Sandbox Code Playgroud)

这将匹配catalog元素,因此<xsl:apply-templates select="cd" />将起作用。