RE: [xsl] alternate bgcolor when node attribute changed

Subject: RE: [xsl] alternate bgcolor when node attribute changed
From: "Morozova, Nelli" <nmorozova@xxxxxxxxxxxxxx>
Date: Fri, 20 Jul 2001 12:03:33 -0400
Hi Jeni,
thank you very much for your response!
the second approach works perfectly (problem is solved!!), 
with the first one I still have a problem (just wanted to understand better
all these things): it returns only 1 row though i call the template, what's
wrong here? could you look please?
<xsl:apply-templates select="/requests/request[1]">
	<xsl:with-param name="previous-bgcolor" select="'#ccccff'" />
</xsl:apply-templates>
<xsl:template match="request">
	<xsl:param name="previous-bgcolor" />
	<xsl:variable name="bgcolor">
		<xsl:choose>
			<xsl:when
test="preceding-sibling::request[1]/@requestId=@requestId">
				<xsl:value-of select="$previous-bgcolor" />
			</xsl:when>
			<xsl:otherwise>
				<xsl:choose>
					<xsl:when test="$previous-bgcolor
='#ffffff'">
						<xsl:text>#ccccff</xsl:text>
					</xsl:when>
					<xsl:otherwise>
						<xsl:text>#ffffff</xsl:text>
					</xsl:otherwise>
				</xsl:choose>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:variable>
		
	<TR bgcolor="{$bgcolor}">
		<!--<TD></TD> elements-->
	</TR>
		<xsl:if test="position()!=last()">
			<xsl:apply-templates
select="/requests/request[position()+1]">
				<xsl:with-param name="previous-bgcolor"
select="$bgcolor" />
			</xsl:apply-templates>
		</xsl:if>
	</xsl:template> 
thank you, again,
best regards,
Nelli

-----Original Message-----
From: Jeni Tennison [mailto:mail@xxxxxxxxxxxxxxxx]
Sent: Thursday, July 19, 2001 9:35 AM
To: Morozova, Nelli
Subject: Re: [xsl] alternate bgcolor when node attribute changed


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
$previous-bgcolor.

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:choose>
      <xsl:when test="preceding-sibling::request[1]/@requestId =
                      @requestId">
        <xsl:value-of select="$previous-bgcolor" />
      </xsl:when>
      <xsl:when test="$previous-bgcolor = '#ffffff'">
        <xsl:text>#ccccff</xsl:text>
      </xsl:when>
      <xsl:otherwise>#ffffff</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
  <tr bgcolor="{$bgcolor}">
    ...
  </tr>
</xsl:template>

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
even).

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

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

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread