Reputation: 295
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
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:
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.
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
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