mark bordelon schrieb am 09.04.2009 um 11:22:04 (-0700):
> In transforming the <syl> tags below into HTML table cells to display
> them, I need to format each cell with a green color with the running
> total of the @length attributes is a multiple of four. Ideally having
> the ability to do running totals in another variable would be great,
> but not the best XSL-esque solution, so I am using axes instead.
What's wrong with variables? You could combine a variable to look up the
result with an approach using the sibling axis, an intermediate result,
and the node-set() extension function. The following example should give
you an idea of how to do such a multi-pass approach in XSLT 1.0. It
should perform quite reasonably.
To speed it up even more, split this into two transformations where the
intermediate result is written to a document which is then used as a
lookup table together with a key in the second transformation.
(I wonder whether it is possible, in 1.0, to have an key work on a
variable that I build while processing? I guess the answer is no.)
Michael Ludwig
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:exsl="http://exslt.org/common&quot;
extension-element-prefixes="exsl"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform&quot;>
<xsl:output indent="yes"/>
<xsl:template match="poem">
<xsl:copy>
<xsl:apply-templates/>
<!-- Check correctness of sum operation: -->
<SUM><xsl:value-of select="sum( //@length )"/></SUM>
</xsl:copy>
</xsl:template>
<xsl:variable name="len-rtf"><!-- Result Tree Fragment -->
<xsl:apply-templates select="//syl[@length]" mode="len"/>
</xsl:variable>
<!-- Build a table to hold @length values for all syl elements. -->
<xsl:template match="syl" mode="len">
<LEN id="{ generate-id() }" len="{ @length }"/>
</xsl:template>
<!-- Build another table to cache sums -->
<xsl:variable name="sums-rtf"><!-- RTF -->
<xsl:apply-templates select="exsl:node-set($len-rtf)/*[1]"/>
</xsl:variable>
<xsl:template match="LEN">
<xsl:param name="sum" select="0"/>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:attribute name="sum">
<xsl:value-of select="$sum + @len"/>
</xsl:attribute>
</xsl:copy>
<xsl:apply-templates select="following-sibling::*[1]">
<xsl:with-param name="sum" select="$sum + @len"/>
</xsl:apply-templates>
</xsl:template>
<!-- Promote the RTF to a node-set so we can use the axes. -->
<xsl:variable name="sums" select="exsl:node-set($sums-rtf)"/>
<xsl:template match="syl">
<xsl:copy>
<xsl:attribute name="running">
<xsl:value-of select="
$sums/LEN[@id = generate-id(current())]/@sum"/>
</xsl:attribute>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()"><!-- copy template -->
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:template>
</xsl:stylesheet>