在XSLT中,<apply-templates> vs <apply-templates select =“...”>

时间:2017-01-25 15:29:59

标签: xslt apply-templates

查看地址http://www.w3schools.com/xml/tryxslt.asp?xmlfile=cdcatalog&xsltfile=cdcatalog_apply下的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:apply-templates/> 

<xsl:apply-templates select="cd"/>

转换不再起作用了...(代码现在看起来如下:)

<?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>

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

  1. 应用模板匹配&#34; cd&#34;
  2. 在模板内&#34; cd&#34;应用其他两个模板(&#34;标题&#34; +&#34;艺术家&#34;)
  3. 更新:

    整个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>
    

    这里是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>
    

1 个答案:

答案 0 :(得分:3)

W3C学校没有告诉你的是XSLT Built-in Template Rules

执行<xsl:apply-templates select="cd"/>时,您将位于文档节点上,该节点是catalog元素的父节点。执行select="cd"将不会选择任何内容,因为cdcatalog元素的子元素,而不是文档节点本身的子元素。只有catalog才是孩子。

(注意catalog是XML的&#34;根元素&#34 ;.XML文档只能有一个根元素。)

但是,当您执行<xsl:apply-templates />时,这相当于<xsl:apply-templates select="node()" />将选择catalog元素。这就是内置模板的用武之地。您的XSLT中没有匹配catalog的模板,因此使用了内置模板。

<xsl:template match="*|/">
   <xsl:apply-templates/>
</xsl:template>

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

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

<xsl:template match="/*">

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