XSLT failing to color rows based on element values?

Question

I need to color rows depending upon data values. If department is "CIT" the row has to be cyan; if it's "COMP", yellow; if it's "IS", pink; anything else, grey. I have everything as it needs to be, but I am getting only grey. That is the only thing with which I'm having an issue.

XML Code:

<?xml version="1.0" encoding="UTF-8"?>
  <catalog>
    <semester name="Fall 2016">
       <class>
           <dept> CIT </dept>
           <number>270/L</number>
           <title>Integrative Programming</title>
           <prereq>CIT 160/L, COMP 182/L; MATH 103, 150A OR 255A</prereq>
       </class>

    <class>
    <dept> SOC  </dept>
    <number>340</number>
    <title>Sociology Of Work</title>
    <prereq>SOC 150</prereq>
   </class>
</semester>
<semester name="Spring 2017">
<class>
    <dept> CIT </dept>
    <number>360</number>
    <title>System Management</title>
    <prereq>CIT 210/L, 270/L</prereq>
</class>
</semester>
<semester name="Fall 2017">
    <class>
    <dept> CIT </dept>
    <number>480/L</number>
    <title> CIT System Design And Implementation1  </title>
    <prereq>COMP 484/L, IS 451</prereq>
</class>
<class>
    <dept> COMP </dept>
    <number>424</number>
    <title>Computer System Security</title>
    <prereq>CIT 360, IS 435</prereq>
</class>
<class>
    <dept> COMP </dept>
    <number>484/L</number>
    <title> Web Engineering I </title>
    <prereq>CIT 360</prereq>
</class>
<class>
    <dept> COMP </dept>
    <number>485</number>
    <title>Human Computer Interaction</title>
    <prereq>CIT 360, IS 451</prereq>
</class>
</semester>
<semester name="Spring 2018">
    <class>
    <dept> CIT </dept>
    <number>481/L</number>
    <title>CIT System Design And Implementation II</title>
    <prereq>CIT 480/L</prereq>
</class>

XSLT Code:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
    <html>
        <body>
            <h2>Path to Graduation</h2>
            <xsl:for-each select="catalog/semester">
                <h2><xsl:value-of select="@name"/></h2>
                <table border="1">
                    <tr bgcolor="lightgreen">
                        <th style="align:center;width:120px;">Catalog Number</th>
                        <th style="align:center;width:350px;">Title</th>
                        <th style="align:center;width:300px;">Prerequisites</th>
                    </tr>
                    <xsl:for-each select="class">
                        <xsl:choose>
                            <xsl:when test="dept='CIT'">
                                <tr bgcolor="cyan">
                                    <td align="center"><xsl:value-of select="dept"/>
                                    <xsl:value-of select="number"/></td>
                                    <td align="center"><xsl:value-of select="title"/></td>
                                    <td align="center"><xsl:value-of select="prereq"/></td>
                                </tr>
                            </xsl:when>
                            <xsl:when test="dept='IS'">
                                <tr bgcolor="pink">
                                    <td align="center"><xsl:value-of select="dept"/>
                                    <xsl:value-of select="number"/></td>
                                    <td align="center"><xsl:value-of select="title"/></td>
                                    <td align="center"><xsl:value-of select="prereq"/></td>
                                </tr>
                            </xsl:when>

                            <xsl:when test="dept='COMP'">
                                <tr bgcolor="yellow">
                                    <td align="center"><xsl:value-of select="dept"/>
                                    <xsl:value-of select="number"/></td>
                                    <td align="center"><xsl:value-of select="title"/></td>
                                    <td align="center"><xsl:value-of select="prereq"/></td>
                                </tr>

                            </xsl:when>
                            <xsl:otherwise>
                                <tr bgcolor="grey">
                                    <td align="center"><xsl:value-of select="dept"/>
                                    <xsl:value-of select="number"/></td>
                                    <td align="center"><xsl:value-of select="title"/></td>
                                    <td align="center"><xsl:value-of select="prereq"/></td>
                                </tr>
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:for-each>
                </table>
            </xsl:for-each>
        </body>
    </html>
</xsl:template>


Show source
| xml   | xslt   2016-12-07 02:12 3 Answers

Answers to XSLT failing to color rows based on element values? ( 3 )

  1. 2016-12-07 03:12

    Your xsl:when tests against dept are failing because of leading and trailing spaces.

    Test against normalize-space(dept) rather than dept to eliminate the problem.

  2. 2016-12-07 04:12

    There are couple of things that you need to fix in your XML or make provision in your XSLT to trim the spaces,

    There are spaces in your node hence your condition was failing,

    Issue node :

    <dept> CIT </dept>
    

    Correct node :

    <dept>CIT</dept>
    

    I have fixed your XML you can find working : http://xsltransform.net/ejivdHb/28

    Or alternatively you can use following approaches to fix your XSL,

    1. Using normalize-space()

      <xsl:when test="normalize-space(dept)='CIT'">
      
    2. Using regular expression.

      <!-- (XSL 2.0) -->
      <xsl:when test="replace(dept, '^\s+|\s+$', '')='CIT'">
      
  3. 2016-12-07 09:12

    Here's a better way of writing your code that not only solves the whitespace problems, it also does it "the XSLT way" which is to use template rules.

    <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
      <html>
        <body>
          <h2>Path to Graduation</h2>
          <xsl:apply-templates select="catalog/semester"/>
        </body>
      </html>
    </xsl:template>
    
    <xsl:template match="semester">
      <h2><xsl:value-of select="@name"/></h2>
      <table border="1">
         <tr bgcolor="lightgreen">
           <th style="align:center;width:120px;">Catalog Number</th>
           <th style="align:center;width:350px;">Title</th>
           <th style="align:center;width:300px;">Prerequisites</th>
         </tr>
         <xsl:apply-templates select="class"/>
      </table>
    </xsl:template>
    
    <xsl:template match="class[normalize-space(dept)='CIT']"
        mode="color">cyan</xsl:template>
    <xsl:template match="class[normalize-space(dept)='IS']"
        mode="color">pink</xsl:template>
    <xsl:template match="class[normalize-space(dept)='COMP']"
        mode="color">yellow</xsl:template>
    <xsl:template match="class" 
        mode="color">grey</xsl:template>
    
    <xsl:template match="class">
      <tr bgcolor="cyan">
        <xsl:attribute name="bgcolor">
          <xsl:apply-templates select="." mode="color"/>
        </xsl:attribute>
        <td><xsl:value-of select="number"/></td>
        <td align="center"><xsl:value-of select="title"/></td>
        <td align="center"><xsl:value-of select="prereq"/></td>
     </tr>
    </xsl:template>
    
    </xsl:stylesheet>
    

    Next week's lesson: the HTML5 table model and CSS.

Leave a reply to - XSLT failing to color rows based on element values?

◀ Go back