开发者

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/>:

  1. Composability.

  2. Looks great in an expression which uses it as a parameter, as return value or as a partial application.

  3. Readability (compactness) and maintainability.

  4. More loose coupling (does not depend on an implicit context node)

  5. Can be referenced in an XPath expression

Shortcomings:

  1. Parameters are identified only by position (not by name)

  2. 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 in makePerson().

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/>:

  1. Composability.

  2. Looks great in an expression which uses it as a parameter, as return value or as a partial application.

  3. Readability (compactness) and maintainability.

  4. More loose coupling (does not depend on an implicit context node)

  5. Can be referenced in an XPath expression

Shortcomings:

  1. Parameters are identified only by position (not by name)

  2. 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 in makePerson().


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>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜