XSL中的“call-template”和“apply-templates”有什么区别?

我是XSLT新手,所以我对这两个标签有点困惑,

<xsl:apply-templates name="nodes"> 

 <xsl:call-template select="nodes"> 

那么你能列出它们之间的区别吗?

<xsl:call-template>与以传统编程语言调用函数相当接近。

您可以在XSLT中定义函数,就像这个输出string的简单函数一样。

 <xsl:template name="dosomething"> <xsl:text>A function that does something</xsl:text> </xsl:template> 

这个函数可以通过<xsl:call-template name="dosomething">

<xsl:apply-templates>有点不同,它是XSLT的真正威力:它可以使用任意数量的XML节点(不pipe你在select属性中定义了什么),迭代它们( 这很重要:apply-templates的工作方式就像一个循环! )并find匹配的模板:

 <!-- sample XML snippet --> <xml> <foo /><bar /><baz /> </xml> <!-- sample XSLT snippet --> <xsl:template match="xml"> <xsl:apply-templates select="*" /> <!-- three nodes selected here --> </xsl:template> <xsl:template match="foo"> <!-- will be called once --> <xsl:text>foo element encountered</xsl:text> </xsl:template> <xsl:template match="*"> <!-- will be called twice --> <xsl:text>other element countered</xsl:text> </xsl:template> 

通过这种方式,您可以放弃对XSLT处理器的一些控制 – 不是您决定程序stream向何处,而是处理器通过为当前正在处理的节点find最合适的匹配。

如果多个模板可以匹配节点,则具有更具体匹配expression式的模板将胜出。 如果存在多个具有相同特异性的匹配模板,则声明最后一个的模板胜出。

您可以更专注于开发模板,并且需要更less的时间来完成“水暖工”。 您的程序将变得更加强大和模块化,嵌套更less,速度更快(因为XSLT处理器针对模板匹配进行了优化)。

用XSLT理解的概念是“当前节点”。 使用<xsl:apply-templates> ,当前节点每次迭代都会继续,而<xsl:call-template>不会更改当前节点。 也就是说. 在一个被调用的模板内引用与之相同的节点. 在通话模板中。 apply-templates不是这种情况。

这是基本的区别。 模板的其他方面也会影响其行为: modepriority ,模板可以同时具有namematch 。 它也影响模板是否已被导入( <xsl:import> )或不。 这些是先进的用途,你可以在你到达时处理它们。

要添加到@Tomalak的好回答:

以下是一些未提及的重要区别

  1. xsl:apply-templatesxsl:call-templates甚至来自xsl:for-each要丰富和深入,因为我们不知道在select的节点上应用什么代码 – 在一般情况下代码对于节点列表的不同节点将是不同的。

  2. 在写入xsl:apply template之后,以及不知道原始作者的人可以使用将要应用的代码

如果XSLT没有<xsl:apply-templates>指令,则FXSL库在XSLT中执行高阶函数(HOF)将不可行

简介 :模板和<xsl:apply-templates>指令是XSLT如何实现和处理多态性的。

参考 :看到这整个线程: http : //www.biglist.com/lists/lists.mulberrytech.com/xsl-list/archives/200411/msg00546.html

xsl:apply-templates通常(但不一定)用于处理当前节点的所有子节点或子节点以及所有适用的模板。 这支持与正在处理的XML的(可能的)recursion匹配的XSLT应用程序的recursion。

另一方面, xsl:call-template更像是一个普通的函数调用。 您只需执行一个(命名)模板,通常使用一个或多个参数。

所以我使用xsl:apply-templates如果我想拦截一个有趣的节点的处理和(通常)注入的东西到输出stream。 典型的(简化的)例子是

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

而对于xsl:call-template我通常会解决一些问题,比如将一些子节点的文本添加到一起,将select的节点集合转换为文本或其他节点集合等等 – 任何你想写的专门的,可重用的函数。

编辑:

作为对您的具体问题文本的补充评论:

 <xsl:call-template name="nodes"/> 

这将调用一个名为“节点”的模板:

  <xsl:template name="nodes">...</xsl:template> 

这是一个不同的语义:

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

…将所有模板应用于当前名为“节点”的XML节点的所有子节点。

function确实类似(除了调用语义,其中call-template需要name属性和相应的名称模板)。

但是,parsing器不会以相同的方式执行。

来自MSDN :

<xsl:apply-templates><xsl:call-template>不会更改当前节点或当前节点列表。

Interesting Posts