Recipe6.1.Convert Simple Named Templates to XSLT Functions


Recipe 6.1. Convert Simple Named Templates to XSLT Functions

Problem

XSLT 1.0 did not support writing XPath functions in XSLT, and named templates are an awkward substitute.

Solution

Prefer XSLT 2.0 functions over named templates when the purpose is solely to compute a result rather then create serialized content. Below I show a potpourri of examples where functions are much more convenient compared to named templates:

<!-- Mathematical computations --> <xsl:function name="ckbk:factorial" as="xs:decimal">    <xsl:param name="n" as="xs:integer"/>    <xsl:sequence select="if ($n eq 0) then 1                           else $n * ckbk:factorial($n - 1)"/>  </xsl:function> <-- Simple mappings --> <xsl:function name="ckbk:decodeColor" as="xs:string">      <xsl:param name="colorCode" as="xs:integer"/>      <xsl:variable name="colorLookup"                   select="('black','red','orange','yellow',                            'green','blue','indigo','violet','white')"/>      <xsl:sequence select="if ($colorCode ge 0 and                                 $colorCode lt count($colorLookup))                             then $colorLookup[$colorCode]                             else 'no color'"/> </xsl:function> <-- String manipulations --> <xsl:function name="ckbk:reverse">     <xsl:param name="input" as="xs:string"/>     <xsl:sequence select="codepoints-to-string(reverse(                            string-to-codepoints($input)))"/> </xsl:function>

Discussion

Recall that named templates are an alternative to templates that are invoked strictly by matching. Named templates act much like procedures in transitional languages because an XSLT programmer explicitly transfers control to a named template via xsl:call-tempate, rather than relying on the more declarative semantics of template matching. A nice feature of XSLT (both 1.0 and 2.0) is that you can mix these styles by giving a template both a pattern and a name.

User-defined XSLT 2.0 functions are not a substitute for named templates. The key question to ask yourself choosing one over the other is: are you simply computing a result or are you creating a reusable content producer? The former is better expressed as a function and the latter as a template. In XSLT 2.0 Programmer's Reference, Michael Kay recommends using functions in cases where you are simply selecting nodes and templates when you are creating new ones, even though XSLT will allow you to use functions for the latter.

This function is selecting nodes:

<xsl:function name="getParts" as="item( )*">   <xsl:param name="startPartId" as="xs:string"/>    <xsl:param name="endPartId" as="xs:string"/>   <xsl:sequence select="//Parts/part[@partId ge $startPartId                                       and @partId le $endPartId]"/>  </xsl:function>

This function is creating new nodes but perhaps a template would make more sense:

<xsl:function name="getPartsElem" as="item( )">       <xsl:param name="startPartId" as="xs:string"/>        <xsl:param name="endPartId" as="xs:string"/>       <Parts>           <xsl:copy-of select="//Parts/part[@partId ge $startPartId                                           and @partId le $endPartId]"/>       <Parts>      </xsl:function>




XSLT Cookbook
XSLT Cookbook: Solutions and Examples for XML and XSLT Developers, 2nd Edition
ISBN: 0596009747
EAN: 2147483647
Year: 2003
Pages: 208
Authors: Sal Mangano

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net