Re: [xsl] Setting background colour according to contents of node

Subject: Re: [xsl] Setting background colour according to contents of node
From: "M. David Peterson" <m.david@xxxxxxxxxx>
Date: Sat, 18 Sep 2004 23:21:18 -0700
Hello Helen,

The best solution for situations of this nature is to create a separate XML file that contains an element and associated value with an attribute whos value can be compared to the data being transformed. To make it simple to edit you can put this data inside your stylesheet and then access it using the document() function. To do this you will need to add a namespace declaration to your xsl:stylesheet element that you will use to enclose the data in. In the stylesheet example I used the namespace "bgcolor" with a value of "http://localhost/bgcolors";. These could have been any name and any URI combination but I try to keep the namespace names and values as obvious as possible so that others using them later on can make sense of whats what. You will also need to remember to add the "exclude-result-prefixes" attribute with the namespace name (if there are multiple namespaces you want excluded separate them by spaces) to ensure the namespace is not included in the output.

So if you had a data file that you wanted to transform that looked like this:

<?xml version="1.0"?>
<data>
  <table bgcolor="w"/>
  <table bgcolor="b"/>
</data>

You could process it with this stylesheet:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; xmlns:bgcolor="http://localhost/bgcolors"; version="1.0" exclude-result-prefixes="bgcolor">


  <bgcolor:colors>
    <color test="w">#fff</color>
    <color test="b">#000</color>
  </bgcolor:colors>

<xsl:variable name="colors" select="document('')/*/bgcolor:colors"/>

  <xsl:template match="/">
    <xsl:apply-templates select="data/table"/>
  </xsl:template>

<xsl:template match="table">
<xsl:variable name="bgcolor" select="$colors//color[@test = current()/@bgcolor]"/>
<table style="background: {$bgcolor}"/>
</xsl:template>


</xsl:stylesheet>

Which would produce this output:

<table style="background: #fff"/>
<table style="background: #000"/>

This seems like it will be the right solution to your problem as it will definitely help you keep things clean and easy to manage while speeding up your transformations by reducing the amount of conditional logic needed to produce the desired output.

Best of luck to you!

<M:D/>



Sean & Helen wrote:
Hi all,
I was trying to set a background colour by setting a variable after checking
the contents of a node. I realized that this would not work unless I used
LOTS of variables since the value of a variable cannot be updated once set.
Does anyone have an easier way to set a colour based on data? The only other
way I can think of is to use an <xsl:choose> but then I have to repeat my
whole table cell code twice (which really adds up for large reports).

This is what I currently have (which is pretty awful):

<xsl:choose>
<xsl:when test="BREAK_3/FIELD_134[1]=Y or BREAK_3/FIELD_135[1]='F'">
     <fo:table-cell background-color="#9DE1DF"> .... contents of the cell
.... </fo:table-cell>
</xsl:when>

<xsl:otherwise>
     <fo:table-cell background-color="white">...exactly the same code for
the contents...</fo:table-cell>
</xsl:otherwise>
</xsl:choose>

TIA for listening to my silly question,
Helen.

Current Thread