BioGeek
BioGeek

Reputation: 22847

Alternating row colors with XSLT and cells with `rowspan`

I have a the following XML file:

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="loci.xsl"?>
<Loci>
    <Locus>
        <Id>LOCUS_1</Id>
        <Alleles>
            <Allele>
                <Name>Allele_1</Name>
                <Description>Description for 1</Description>
            </Allele>
        </Alleles>
    </Locus>
    <Locus>
        <Id>LOCUS_2</Id>
        <Alleles>
            <Allele>
                <Name>Allele_2_a</Name>
                <Description>Description for 2 a</Description>
            </Allele>
            <Allele>
                <Name>Allele_2_b</Name>
                <Description>Description for 2 b</Description>
            </Allele>
        </Alleles>
    </Locus>
    <Locus>
        <Id>LOCUS_3</Id>
        <Alleles>
            <Allele>
                <Name>Allele_3</Name>
                <Description>Description for 3</Description>
            </Allele>
        </Alleles>
    </Locus>
</Loci>

that I transform to an HTML table with the following XSL, and style with the embedded CSS:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <html>
  <head>
<style type="text/css">
#report
{
    font-family: "Lucida Sans Unicode", "Lucida Grande", Sans-Serif;
    font-size: 12px;
    margin: 45px;
    width: 90%;
    text-align: left;
    border-collapse: collapse;
    color: #039;
}
#report th
{
    font-size: 16px;
    font-weight: normal;
    padding: 10px 8px;
    color: #039;
    text-align: left;
    border-right: 1px solid #9baff1;
    border-left: 1px solid #9baff1;
    border-top: 2px solid #9baff1;
    border-bottom: 2px solid #9baff1;
}
#report td
{
    padding: 5px;
    color: #669;
    border-right: 1px solid #aabcfe;
    border-left: 1px solid #aabcfe;
}
#report  tr:nth-child(even) 
{ 
    background: #e8edff; 
}
</style>
</head>
  <body>
    <table border="1" id="report">
      <tr>
        <th>Locus</th>
        <th>Allele</th>
        <th>Description</th>
      </tr>
      <xsl:for-each select="Loci/Locus">
        <xsl:for-each select="Alleles/Allele">
          <tr>
            <xsl:if test="position() = 1">
              <td rowspan="{last()}">
                <xsl:value-of select="ancestor::Locus[1]/Id"/>
              </td>
            </xsl:if>
            <td><xsl:value-of select="Name"/></td>
            <td><xsl:value-of select="Description"/></td>
          </tr>
        </xsl:for-each>
      </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

The result looks like this:

table

However, I would like the zebra striping to alternate depending on the first column.

So the row for the first locus completely in purple is OK, but for the second locus I would also like the cells with Allele_2_b and Description for 2 b in white and then I would like the whole row for the third locus in purple again.

How do I accomplish this?

Upvotes: 1

Views: 1378

Answers (1)

JLRishe
JLRishe

Reputation: 101700

How about this:

  <xsl:for-each select="Loci/Locus">
    <xsl:variable name="oddRow" select="position() mod 2" />
    <xsl:for-each select="Alleles/Allele">
      <tr>
        <xsl:if test="$oddRow">
          <xsl:attribute name="class">alt-row</xsl:attribute>
        </xsl:if>
        <xsl:if test="position() = 1">
          <td rowspan="{last()}">
            <xsl:value-of select="ancestor::Locus[1]/Id"/>
          </td>
        </xsl:if>
        <td><xsl:value-of select="Name"/></td>
        <td><xsl:value-of select="Description"/></td>
      </tr>
    </xsl:for-each>
  </xsl:for-each>

Then you can simply use CSS to apply background shading to the alt-row class.

Upvotes: 2

Related Questions