XSL recursive call - xsl:functions vs xsl:template with call template
I have basic query. I have been using xsl:template and use call tempate to make recursive calls to the template. I see xsl:function which also has feasibility to make recursive function calls like recursive template calls and achieve the same. When should xsl:function be used and when should xsl:template be used. I am not sure what is the diffence between the two and when should they be used. What are their special fea开发者_Python百科tures of each of them. Can someone please help me understand this better.
This is how I replied to a similar question almost 3 years ago:
Benefits of using
<xsl:function/>
:
Composability.
Looks great in an expression which uses it as a parameter, as return value or as a partial application.
Readability (compactness) and maintainability.
More loose coupling (does not depend on an implicit context node)
Can be referenced in an XPath expression
Shortcomings:
Parameters are identified only by position (not by name)
Can be impure (can have a side effect, such as creating new node(s)) and just by looking at an expression referencing this function people may not understand that it has a side effect. However this possibility of confusion can be eliminated if proper naming is used.
I tend always to use
<xsl:function/>
. In the cases when the function creates new node(s) I follow the convention of starting its local-name with the string "make", as inmakePerson()
.
I can only add to this:
Always when possible use <xsl:function>
.
In XPath 3.0 functions are a first-class data type of the language (aka HOF -- Higher-Order Functions). They can be passed as parameters or returned as the result to/from other functions.
This is an incredibly powerful leap forward from using named templates.
Conceptually xsl:apply-templates
is a map with a polymorphic function expressed for all the rules you have declared. xsl:function
declares a "regular" function you can use in any any other instruction or declaration accepting XPath expressions. xsl:call-template
instruction "invokes" a particular named template (you could think of this as a function in some way).
Because this, there are differences about how evaluation context is involve in each one: xsl:apply-templates
define a new context list from which the context node is taken as well as the proximity position; xsl:function
doesn't have context node defined (it's an error to rely on it); xsl:call-template
doesn't change the evaluation context.
Other evident difference is their relationship with the output: both xsl:apply-templates
and xsl:call-template
as XSLT instructions output their constructed sequence; xsl:function
as part of an XPath expression it doesn't.
I found Dimitre's response - http://www.stylusstudio.com/xsllist/200811/post00400.html - helpful.
Benefits of using
<xsl:function/>
:
Composability.
Looks great in an expression which uses it as a parameter, as return value or as a partial application.
Readability (compactness) and maintainability.
More loose coupling (does not depend on an implicit context node)
Can be referenced in an XPath expression
Shortcomings:
Parameters are identified only by position (not by name)
Can be impure (can have a side effect, such as creating new node(s)) and just by looking at an expression referencing this function people may not understand that it has a side effect. However this possibility of confusion can be eliminated if proper naming is used.
I tend always to use
<xsl:function/>
. In the cases when the function creates new node(s) I follow the convention of starting its local-name with the string "make", as inmakePerson()
.
Templates are useful when you have the requirement to store the results of each recursion into a variable as a attribute ( at the end of each recursion before calling the next ).
**Example:**
<xsl:variable name="test">
<record>
<xsl:call-template name="templateRecursion">
<xsl:with-param name="xyz" select="xyz"/>
</xsl:call-template>
<record>
</xsl:variable>
**templateRecursion:**
<xsl:template name="templateRecursion">
<!-- Do processing -->
<xsl:attribute name="" value=""
</xsl:template>
So, the variable test will have
<record>
<attribute_name="" value=""/>
.
.
</record>
精彩评论