首页 > 技术文章 > call-template与apply-templates的区别

ghpaas 2014-07-09 12:51 原文

之前我用了比较多的call-template,后来说着说着,突然发现apply-templates在大部分的场景下比call-template好用,也更安全一些。

比如,apply-templates可以通过select属性来选择具体要匹配的node-set,如果不存在这样的node-set,就不进行转换,这就比call-template安全了一些,因为后者是直接调用,不管存不存在某些节点;其次,apply-templates和call-template一样,可以通过<xsl:param/>接受参数;此外,当我们定义多个template时,这些templates不可以有重复的name,但可以有重复的match,重复的template通过priority来确定该用哪个template来进行转换,如果多个template有相同的priority的话,则选择最后出现的那个。

似乎apply-templates功能比call-template强。就目前我所用到的普通转换来说,用apply-templates是比较安全的,并且可读性也会高一些。但是在XSLT 1.0中,如果想要实现像XSLT 2.0中function一样的功能的话,用call-template就比较方便了,比如递归调用(Recursive function)。下面是一个例子:

<xsl:template name=”longest-speech” as=”element(SPEECH)?”>

<xsl:param name=”list” as=”element(SPEECH)*”/>

<xsl:choose>

<xsl:when test=”$list”>

<xsl:variable name=”first” select=”count($list[1]/LINE)” as=”xs:integer”/>

<xsl:variable name=”longest-of-rest” as=”element(SPEECH)?”>

<xsl:call-template name=”longest-speech”>

<xsl:with-param name=”list” select=”$list[position()!=1]“/>

</xsl:call-template>

</xsl:variable>

<xsl:choose>

<xsl:when test=”$first gt count($longest-of-rest/LINE)”>

<xsl:value-of select=”$list[1]“/>

</xsl:when>

<xsl:otherwise>

<xsl:value-of select=”$longest-of-rest”/>

</xsl:otherwise>

</xsl:choose>

</xsl:when>

</xsl:choose>

</xsl:template>

<xsl:template match=”/”>

<longest-speech>

<xsl:call-template name=”longest-speech”>

<xsl:with-param name=”list” select=”//SPEECH”/>

</xsl:call-template>

</longest-speech>

</xsl:template>

待转换的xml是:

<?xml version=”1.0″?>

<SCENE><TITLE>SCENE I. Venice. A street.</TITLE>

<STAGEDIR>Enter RODERIGO and IAGO</STAGEDIR>

<SPEECH>

<SPEAKER>RODERIGO</SPEAKER>

<LINE>Tush! never tell me; I take it much unkindly</LINE>

<LINE>That thou, Iago, who hast had my purse</LINE>

<LINE>As if the strings were thine, shouldst know of this.</LINE>

</SPEECH>

<SPEECH>

<SPEAKER>IAGO</SPEAKER>

<LINE>’Sblood, but you will not hear me:</LINE>

<LINE>If ever I did dream of such a matter, Abhor me.</LINE>

</SPEECH>

etc.

</SCENE>

在关于使用call-template和apply-templates的性能差别上,Sam Judson (Wrox 技术编辑)有言:

In terms of raw performance xsl:call-template is likely to be faster, as you are calling a specific named template, rather than telling the XSLT processor to pick the template which best matches.

There are certainly things you can do with xsl:call-template that you can’t do with xsl:apply-templates, such as recursive templates which are very powerful.

xsl:apply-templates is however the more flexible and extensible, due to its combined use of the match patterns, modes and priorities.

我觉得概括的不错,言简意赅,就以此作为结尾吧。

推荐阅读