This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: Antwort: comments. (Re: key() Re: Saxon VS XT)
- To: xsl-list at mulberrytech dot com
- Subject: Re: Antwort: comments. (Re: key() Re: Saxon VS XT)
- From: Jeni Tennison <jeni at friday dot u-net dot com>
- Date: Sun, 13 Aug 2000 10:43:33 +0100
- Reply-To: xsl-list at mulberrytech dot com
[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