XSLT: number of times template called

Discussion in 'XML' started by Ralph Snart, May 12, 2005.

  1. Ralph Snart

    Ralph Snart Guest

    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-
    Ralph Snart, May 12, 2005
    #1
    1. Advertising

  2. (Ralph Snart) writes:

    > 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
    David Carlisle, May 12, 2005
    #2
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. djskrill
    Replies:
    9
    Views:
    697
    djskrill
    Oct 1, 2003
  2. Apricot
    Replies:
    4
    Views:
    523
    velthuijsen
    Apr 16, 2004
  3. Jack Steven
    Replies:
    2
    Views:
    430
    Chris Rebert
    Mar 9, 2009
  4. Radu
    Replies:
    7
    Views:
    708
    charlie_Stell
    Aug 28, 2009
  5. Felix
    Replies:
    1
    Views:
    337
    Felix
    Sep 29, 2006
Loading...

Share This Page