Re: Antwort: comments. (Re: key() Re: Saxon VS XT)

Subject: Re: Antwort: comments. (Re: key() Re: Saxon VS XT)
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Sun, 13 Aug 2000 10:43:33 +0100
[Resent from recognised email address]

Paul Tchistopolskii wrote:
>Because  I'm just mortal hacker  - I simply don't understand 
>how to avoid call-template

If you have a named template:

<xsl:template name="XXX">
...
</xsl:template>

called by:

<xsl:call-template name="XXX" />

(with or without any parameters that you care to define), then this can
*always* be rewritten as a moded template matching anything:

<xsl:template match="node()|/" mode="XXX">
...
</xsl:template>

[Aside: I would have thought that match="node()" would work, but testing
with SAXON 5.4.1 shows that the this does not match the root node.  Is this
a bug?]

and called by:

<xsl:apply-templates select="." mode="XXX" />

(with or without any parameters that you care to define).

So you can always avoid xsl:call-templates completely if you wanted to.
Named templates are simply a better choice when the current node has no
effect on the result of the template.

>but of course I'l appreciate 
>the snippet of  some code ( in the 'true' transformation  language, 
>'procedural' , 'declaratibve'  or whatever  ) which will show, say, 
>calculation of max value  of some list  -  written without 
>call-template AKA procedural hint.

I'm not sure what the 'true' transformation language is, but anyway:

If the list is declared in XML, you can sort the list of values in
descending order and pick off the first value:

<xsl:variable name="maximum">
  <xsl:for-each select="$list">
    <xsl:sort select="." order="descending" />
    <xsl:if test="position() = 1">
      <xsl:value-of select="." />
    </xsl:if>
  </xsl:for-each>
</xsl:variable>

If the list were a string separated by commas, say, then you have to use
recursion, and the current node doesn't matter, so named templates are the
best choice, but you can use xsl:apply-templates instead if you want to:

<xsl:variable name="maximum">
  <xsl:apply-templates select="." mode="maximum">
    <xsl:with-param name="list" select="concat($list, ', ')" />
  </xsl:apply-templates>
</xsl:variable>

<xsl:template match="node()|/" mode="maximum">
  <xsl:param name="list" />
  <xsl:variable name="first" select="substring-before($list, ',')" />
  <xsl:variable name="rest" select="substring-after($list, ',')" />
  <xsl:choose>
    <xsl:when test="not(normalize-space($rest))">
      <xsl:value-of select="$first" />
    </xsl:when>
    <xsl:otherwise>
      <xsl:variable name="max">
        <xsl:apply-templates select="." mode="maximum">
          <xsl:with-param name="list" select="$rest" />
        </xsl:apply-templates>
      </xsl:variable>
      <xsl:choose>
        <xsl:when test="$first > $max">
          <xsl:value-of select="$first" />
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$max" />
        </xsl:otherwise>
      </xsl:choose>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

Perhaps modes are regarded as 'procedural hints' too.

Cheers,

Jeni


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread