XSLT Cookbook, from O'Reilly. Chapter 8 XML to HTML | 16

XSLT Cookbook, Chapter 8: XML to HTML

You can avoid having to define two attribute sets that perform the same function by pushing the logic into templates:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   
  <xsl:output method="html"/>
   
  <xsl:attribute-set name="gain-loss-font">
    <xsl:attribute name="color">
      <xsl:apply-templates select="." mode="gain-loss-font-color"/>
    </xsl:attribute>
  </xsl:attribute-set>      
   
<xsl:template match="stock" mode="gain-loss-font-color">
    <xsl:choose>
      <xsl:when test="(current - paid) * qty >= 0">black</xsl:when>
      <xsl:otherwise>red</xsl:otherwise>
    </xsl:choose>
</xsl:template>
   
<xsl:template match="property" mode="gain-loss-font-color">
    <xsl:choose>
      <xsl:when test="appriasal - paid  >= 0">black</xsl:when>
      <xsl:otherwise>red</xsl:otherwise>
    </xsl:choose>
</xsl:template>
   
... 
   
</xsl:stylesheet>

You might be uncomfortable incorporating any purely stylistic attributes such as colors, fonts, and the like into your XSLT transformation. Perhaps it is not your job—but the job of a company style czar—to decide how to render gains and losses. In this case, you can simply classify the elements and defer stylizing decisions to a separately defined stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   
  <xsl:output method="html"/>
   
  <xsl:attribute-set name="gain-loss">
    <xsl:attribute name="class">
      <xsl:apply-templates select="." mode="gain-loss"/>
    </xsl:attribute>
  </xsl:attribute-set>      
   
<xsl:template match="stock" mode="gain-loss">
    <xsl:choose>
      <xsl:when test="(current - paid) * qty >= 0">gain</xsl:when>
      <xsl:otherwise>loss</xsl:otherwise>
    </xsl:choose>
</xsl:template>
   
<xsl:template match="property" mode="gain-loss">
    <xsl:choose>
      <xsl:when test="appriasal - paid  >= 0">gain</xsl:when>
      <xsl:otherwise>loss</xsl:otherwise>
    </xsl:choose>
</xsl:template>
   
<xsl:template match="portfolio">
    <html>
     <head>
      <title>My Portfolio</title>
      <link  rel="stylesheet"  type="text/css"  href="portfolio.css"/>
     </head>
   
     ...
    
</xsl:template>
   
<xsl:template match="stock">
  <tr>
    <td><xsl:value-of select="symbol"/></td>
    <td align="right"><xsl:value-of select="current"/></td>
    <td align="right"><xsl:value-of select="paid"/></td>
    <td align="right"><xsl:value-of select="qty"/></td>
    <td align="right" xsl:use-attribute-sets="gain-loss">
      <xsl:value-of 
            select="format-number((current - paid) * qty, '#,##0.00')"/>
    </td>
  </tr>
</xsl:template>     
   
<xsl:template match="property">
  <tr>
    <td><xsl:value-of select="address"/></td>
    <td align="right"><xsl:value-of select="paid"/></td>
    <td align="right"><xsl:value-of select="appriasal"/></td>
    <td align="right" xsl:use-attribute-sets="gain-loss">
      <xsl:value-of 
             select="format-number(appriasal - paid, '#,##0.00')"/>
    </td>
  </tr>
</xsl:template>     
   
</xsl:stylesheet>

The style czar can then decide how to render <td class="gain"> and <td class="loss"> by using portfolio.css, as shown in Example 8-1.

Example 8-1. portfolio.css

td.gain
{
     color:black;
}
   
td.loss
{
     color:red;
     font-weight:700;
}

Created: March 27 2003
Revised: May 5, 2003

URL: http://webreference.com/programming/xslt/cookbook/chap8/2