Search code examples
xmlxsltxpathxslt-2.0xpath-2.0

XML transformation grouping using XSLT2


I'm new to XSLT and I have the following issue when trying to use XSLT2 and the altovaXML processor.

<?xml version="1.0"?>
 <document>
  <row>
   <WEEK>11</WEEK>
   <PERIOD>201103</PERIOD>
   <ILPROD>some item</ILPROD>
   <CNME>some name</CNME>
   <QTY>100</QTY>
   <SP>40</SP>
   <REV>4000</REV>
   <COST>2000</COST>
   <VA>2000</VA>
   <VAP>50</VAP>
  </row>
</document>

My XSL is as follows

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>

<xsl:template match="/">
  <html>
  <body>
  <h2>Some text</h2>
  <table border="1">
    <tr bgcolor="#9acd32">
      <th>Analysis</th>
    </tr>
    <xsl:for-each-group select="document/row" group-by="ILPROD">
    <xsl:for-each select="current-group()">
      <tr>
      <td><xsl:value-of select="WEEK"/></td>
      <td><xsl:value-of select="PERIOD"/></td>
      <td><xsl:value-of select="ILPROD"/></td>
    </tr>
    </xsl:for-each>
    <tr><td>&nbsp</td></tr>
    </xsl:for-each-group>
    </table>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>

Very simply I'm trying to group by the "ILPROD" child node and output a blank space after each group. Sounds easy but I'm obviously making a basic error because the processor says it can't load the document. It works fine if I remove the grouping.

Any ideas where I'm going wrong ?


Solution

  • Try using the below instead of &nbsp (which is missing a semi-colon by the way):

    <tr><td colspan="3"><br></br></td></tr>
    

    And don't forget to change output to html:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
    <xsl:output method="html"/>
    
    <xsl:template match="/">
      <html>
      <body>
      <h2>Some text</h2>
      <table border="1">
        <tr bgcolor="#9acd32">
          <th>Analysis</th>
        </tr>
        <xsl:for-each-group select="document/row" group-by="ILPROD">
        <xsl:for-each select="current-group()">
          <tr>
          <td><xsl:value-of select="WEEK"/></td>
          <td><xsl:value-of select="PERIOD"/></td>
          <td><xsl:value-of select="ILPROD"/></td>
        </tr>
        </xsl:for-each>
        <tr><td colspan="3"><br></br></td></tr>
        </xsl:for-each-group>
        </table>
      </body>
      </html>
    </xsl:template>
    
    </xsl:stylesheet>
    

    When I run this in Altova XML, I get the correct output:

    <html>
        <body>
            <h2>Some text</h2>
            <table border="1">
                <tr bgcolor="#9acd32">
                    <th>Analysis</th>
                </tr>
                <tr>
                    <td>11</td>
                    <td>201103</td>
                    <td>some item</td>
                </tr>
                <tr>
                    <td colspan="3"><br></td>
                </tr>
            </table>
        </body>
    </html>