xsl:call-template的行为与xsl:apply-templates不同?

时间:2016-02-19 22:01:45

标签: xml xslt

为什么 xsl:template ""列出所有属性"在内联运行而不是被命名为命名模板时,行为会有所不同吗?

我有这个XML:

<?xml version="1.0" encoding="UTF-8"?>
<cars>
  <car model="Focus" manufacturer="Ford" year="2000" />
  <car model="Golf" manufacturer="Volkswagen" year="1999" />
  <car model="Camry" manufacturer="Toyota" year="1999" />
  <car model="Civic" manufacturer="Honda" year="2000" />
  <car model="Prizm" manufacturer="Chevrolet" year="2000" />
</cars>

如果我将以下XSL应用于该XML(在XSL调试器中,以便我可以看到发生了什么),那么内联模板匹配=&#34; car&#34; 遍历所有 @model 属性。

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

<!-- When applied inline this structure iterates through all @model attributes. -->
  <xsl:template match="car">
    <xsl:value-of select="@model"/>
  </xsl:template>

</xsl:stylesheet>

结果:

Focus
Golf
Camry
Civic
Prizm

正是我想要的。但现在我想通过 xsl:call-template 将相同的 xsl:template 结构应用为命名模板,如下所示:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

  <xsl:template match="car">
    <xsl:call-template name="models"/>
  </xsl:template>

<!-- When applied via call-template, lists one @model attribute, then returns -->
  <xsl:template name="models">
    <xsl:value-of select="@model"/>
  </xsl:template>

</xsl:stylesheet>

在此示例中只有一个 name = 模板,结果是相同的,因为(我的XSL调试器显示我)XSL重复应用 xsl:call-template 指令,不是因为xsl:template name =&#34; models&#34; 遍历所有 @model 属性,就像在内联时一样。

有人可以解释为什么(如果你允许类比)被叫XSL&#34;子程序&#34;一次迭代后返回,当它没有“退出”时#34;当它以内联方式运行时的循环?

请注意我明白有明确的XSL循环结构。我已经使用 mode = 模板生成了我想要的多属性列表。那些不是我正在寻找的答案。我的问题是为什么基本相同的 xsl:template 结构的内联与被调用行为的不同取决于它是内联还是被调用。 THX ...

1 个答案:

答案 0 :(得分:2)

  

如果我将以下XSL应用于该XML(在XSL调试器中,我可以   看看发生了什么),那么内联模板匹配=“汽车”迭代   通过所有@model属性。

不,不完全是。这是您正在发生的事情的内部模型需要调整的地方。

在第一次XSLT转换中,匹配car的模板不会迭代通过任何内容。它重复匹配。它能够匹配,因为<xsl:apply-templates />模板中出现/cars并为car的每个子节点(包括cars元素)调用模式匹配,因为

<xsl:apply-templates/> 

完全相同
<xsl:apply-templates select="node()"/>