Babak Bst
Babak Bst

Reputation: 295

difference between <xsl:apply-template> and <xsl:call-template>?

would you please explain me the difference between<xsl:apply-template> and <xsl:call-template> and when should i use <xsl:call-template> ?
thank you

Upvotes: 6

Views: 11039

Answers (2)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243459

would you please explain me the difference between <xsl:apply-template> and <xsl:call-template> and when should i use <xsl:call-template> ?

One can use <xsl:call-template> but almost never should.

It is in the spirit of XSLT to allow the XSLT processor to determine exactly which template best matches a node and to decide to use this template for processing that node. This gives us clean, easy and powerful extensibility and polymorphism.

In general, comparing xsl:apply-templates to xsl:call-template is similar to comparing the invoking of a virtual method from a base class to that of calling a non-virtual method directly.

Here are some important differences:

  1. xsl:apply-templates is much richer and deeper than xsl:call-templates and even from xsl:for-each, simply because we don't know what code will be applied on the nodes of the selection -- in the general case this code will be different for different nodes of the node-list.

  2. The code that will be applied can be written way after the xsl:apply-templates was written and by people that do not know the original author.

The FXSL library's implementation of higher-order functions (HOF) in XSLT wouldn't be possible if XSLT didn't have the <xsl:apply-templates> instruction.

Summary: Templates and the <xsl:apply-templates> instruction is how XSLT implements and deals with polymorphism. One can and should avoid using xsl:call-template, which doesn't allow polimorphism and limits reusability and flexibility.

Reference: See this whole thread: http://www.stylusstudio.com/xsllist/200411/post60540.html

Upvotes: 3

Emma Burrows
Emma Burrows

Reputation: 5144

On a very basic level, you use <xsl:apply-templates> when you want to let the processor handle nodes automatically, and you use <xsl:call-template/> when you want finer control over the processing. So if you have:

<foo>
    <boo>World</boo>
    <bar>Hello</bar>
</foo>

And you have the following XSLT:

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

<xsl:template match="bar">
    <xsl:value-of select="."/>
</xsl:template>

<xsl:template match="boo">
    <xsl:value-of select="."/>
</xsl:template>

You will get the result WorldHello. Essentially, you've said "handle bar and boo this way" and then you've let the XSLT processor handle these nodes as it comes across them. In most cases, this is how you should do things in XSLT.

Sometimes, though, you want to do something fancier. In that case, you can create a special template that doesn't match any particular node. For example:

<xsl:template name="print-hello-world">
    <xsl:value-of select="concat( bar, ' ' , boo )" />
</xsl:template>

And you can then call this template while you're processing <foo> rather than automatically processing foo's child nodes:

<xsl:template match="foo">
    <xsl:call-template name="print-hello-world"/>
</xsl:template>

In this particular artificial example, you now get "Hello World" because you've overriden the default processing to do your own thing.

Hope that helps.

Upvotes: 13

Related Questions