0

Im having some troubles in creating a table where the Rowspan of one column needs to be specified. I have this xml

<?xml version="1.0" encoding="UTF-8"?>
<catalog>
  <artist>
    <name>artist1</name>
    <cd>cd1</cd>
    <cd>cd2</cd>
    <cd>cd3</cd>  
  </artist>
<artist>
    <name>artist2</name>
    <cd>cd2</cd>
    <cd>cd4</cd>  
  </artist>
<artist>
    <name>artist3</name>
    <cd>cd5</cd>
    <cd>cd4</cd>  
  </artist>

</catalog>

And this XSL

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html> 
<body>
  <h2>My CD Collection</h2>
  <table border="1">
    <tr bgcolor="#9acd32">
      <th style="text-align:left">Artist</th>
      <th style="text-align:left">CD</th>
    </tr>
    <xsl:for-each select="catalog/artist">
    <tr>
      <td rowspan="{count(cd)}">
          <xsl:value-of select="count(cd)"/>
          <xsl:value-of select="name"/>
      </td>

    <xsl:for-each select="cd">
           <tr>
             <td><xsl:value-of select="."/></td>
           </tr>
    </xsl:for-each>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

The problem is the follows: When the rowspan is count(cd), it does not display properly as you can see in the figure enter image description here But, if I put count(cd)+1 instead of count(cd) (which does not make sense since I want the rowspan the same size as count(cd) it displays correctly, but when I generate the HTML, if the window is smaller, it creates an extra line. Due to having an extra row. enter image description here

Do you have any ideas?

aa bb
  • 3
  • 2

1 Answers1

0

count(cd) is showing the right number. It's just that your HTML table is badly structured.

One problem is that you have the closing </tr> in the wrong place, which results in a row being nested in a row.

But your main problem is that the first cd needs to go in the same row as the one with the artist name.

Try this XSLT instead

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html> 
<body>
  <h2>My CD Collection</h2>
  <table border="1">
    <tr bgcolor="#9acd32">
      <th style="text-align:left">Artist</th>
      <th style="text-align:left">CD</th>
    </tr>
    <xsl:for-each select="catalog/artist">
    <tr>
      <td rowspan="{count(cd)}">
        <xsl:value-of select="count(cd)"/>
        <xsl:value-of select="name"/>
      </td>
      <td><xsl:value-of select="cd[1]"/></td>
    </tr>
    <xsl:for-each select="cd[position() > 1]">
       <tr>
         <td><xsl:value-of select="."/></td>
       </tr>
    </xsl:for-each>
    </xsl:for-each>
  </table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

Alternatively, you could write it this way

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html> 
<body>
  <h2>My CD Collection</h2>
  <table border="1">
    <tr bgcolor="#9acd32">
      <th style="text-align:left">Artist</th>
      <th style="text-align:left">CD</th>
    </tr>
    <xsl:for-each select="catalog/artist">
       <xsl:variable name="cds" select="count(cd)" /> 
       <xsl:variable name="artist" select="name" /> 
       <xsl:for-each select="cd">
       <tr>
         <xsl:if test="position() = 1">
           <td rowspan="{$cds}">
             <xsl:value-of select="$cds"/>
             <xsl:value-of select="$artist"/>
           </td>
         </xsl:if>
         <td><xsl:value-of select="."/></td>
       </tr>
    </xsl:for-each>
    </xsl:for-each>
  </table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Tim C
  • 70,053
  • 14
  • 74
  • 93
  • Worked like a charm!! I just don't get one thing. Let's talk as cells, so we have an artist with 2 cd's, which make a 2x2 matrix. My question is when you define cells (1,1) and (2,1) in rowspan, why do you have to define also the cell (1,2) and then define the remaining cell (2,2) in the for each if the element is greater than 1? – aa bb Mar 07 '19 at 16:29
  • Rowspan can be confusing and difficult to explain! Perhaps this question helps? https://stackoverflow.com/questions/9830506/how-do-you-use-colspan-and-rowspan-in-html-tables – Tim C Mar 07 '19 at 17:24
  • Im having some trouble related to this. Because I chose different td for the first element and the rest in a iteration, in the CSS file, when I want to select row 2, how should I proceed? .class tr td:nth-child(2), it only selects the first row, because it assumes 2nd row to be the first td – aa bb Mar 07 '19 at 21:32
  • I am not sure how CSS works where you have rowspan (and so a "td" in the first position that is actually in the second column). One suggestion would be to give the td elements in column 2 a specific class name, and style that instead. – Tim C Mar 08 '19 at 09:00