XSLT: number of times template called

R

Ralph Snart

i'm trying to do the classic alternating table row colors trick.
i can't use position() mod 2 in this case because sometimes the
template is called but it decides not to print the particular element.
i really need to keep track of how many times it has printed something,
but since you can't modify variables in xslt, i have no idea how to
do it.

the fragment looks something like this:

<xsl:template match="story">
<xsl:param name="no_repeats"/>
<xsl:if test="following-sibling::*[1]/id != id or position() = last() or $no_repeats != 1">
<tr>
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="position() mod 2 = 0">dark</xsl:when>
<xsl:eek:therwise>light</xsl:eek:therwise>
</xsl:choose>
</xsl:attribute>
<td>

any ideas?
-rs-
 
D

David Carlisle

i'm trying to do the classic alternating table row colors trick.
i can't use position() mod 2 in this case because sometimes the
template is called but it decides not to print the particular element.
i really need to keep track of how many times it has printed something,
but since you can't modify variables in xslt, i have no idea how to
do it.

Even if you could modify variables in xslt it wouldn't work, as a
processor is not obliged to execute the templates in natural order, it
can execute them in any order it wants (and in particular it can execute
them in parallel) If it can spot that two of the input nodes are
equivalent and the matching template doesn't use context information
like position() it need not evaluate the template multiple times at all,
it can just copy the result. So the value of a variable would be
completely undefined in that case as it depends on internal processor
behaviour.
the fragment looks something like this:

<xsl:template match="story">
<xsl:param name="no_repeats"/>
<xsl:if test="following-sibling::*[1]/id != id or position() = last() or $no_repeats != 1">
<tr>
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="position() mod 2 = 0">dark</xsl:when>
<xsl:eek:therwise>light</xsl:eek:therwise>
</xsl:choose>
</xsl:attribute>
<td>

any ideas?
-rs-

The easiest is probably to change that to

<xsl:template match="story">
<xsl:param name="no_repeats"/>
<tr>
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="position() mod 2 = 0">dark</xsl:when>
<xsl:eek:therwise>light</xsl:eek:therwise>
</xsl:choose>
</xsl:attribute>

and change
<xsl:apply-templates select="story"/> in the template matching the
parent to

<xsl:apply-templates select="story[following-sibling::*[1]/id != id or position() = last() or $no_repeats != 1]"/>

So that you only select the elements you want so position() counts the
elements you want rather than selecting everything then throwing some
away.

David
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,812
Latest member
GracielaWa

Latest Threads

Top