Re: [xsl] alternate bgcolor when node attribute changed

Subject: Re: [xsl] alternate bgcolor when node attribute changed
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Thu, 19 Jul 2001 14:35:16 +0100
Hi Nelli,

> I have a question about how to alternate bgcolor attribute of <TR>
> element if some attribute of a node is changed, so a group of rows
> with the same attribute requestId=15 would have the same bgcolor
> (white - #ffffff) the next group with different requestId=21 would
> has different bgcolor (light blue - "#ccccff) and next group has
> again white bgcolor and so on, I cannot use mod operator since
> requestId attribute is not changing evenly and besides user can sort
> by any column. (So if requestId is changed in comparison with
> previous row bgcolor should change otherwise it should remain the
> same.)

There are two approaches that you could take to this. The first is to
use template parameters to keep track of the colour for a particular
row. Rather than iterate over the requests using xsl:for-each, instead
apply templates to the first one:

  <xsl:apply-templates select="/requests/request[1]" />

and then have a template that matches them, and takes a
$previous-bgcolor parameter holding the bgcolor of the previous
request. If this template has the same requestId as the previous one,
then you want to use the $previous-bgcolor, otherwise you want to
change it to the other colour. In either case, you need to apply
templates to the next request, passing this new bgcolor as the

In essence, you're stepping through the requests one by one, each one
telling the next one what colour it was.

<xsl:template match="request">
  <xsl:param name="previous-bgcolor" select="'#ccccff'" />
  <xsl:variable name="bgcolor">
      <xsl:when test="preceding-sibling::request[1]/@requestId =
        <xsl:value-of select="$previous-bgcolor" />
      <xsl:when test="$previous-bgcolor = '#ffffff'">
  <tr bgcolor="{$bgcolor}">

The other way you could do it is to iterate over only those requests
whose requestId is *different* from the previous request (i.e. the
first request in each group). You can then work out the colour based
on the position of the request in this set (white if odd, sky blue if

  <xsl:for-each select="/requests/request
      [not(preceding-sibling::request[1]/@requestId = @requestId)]">
    <xsl:variable name="requestId" select="@requestId" />
    <xsl:variable name="bgcolor">
        <xsl:when test="position() mod 2 = 1">#ffffff</xsl:when>
    <xsl:for-each select=".|following-sibling::request[@requestId =
      <tr bgcolor="{bgcolor}">

In both these approaches I've assumed that the request elements are
sorted by their requestId attribute, so that all the request elements
with the same requestId are grouped together in the source.

I hope that helps,


Jeni Tennison

 XSL-List info and archive:

Current Thread