GNOME Bugzilla – Bug 52905
global variable not resolving to nodeset?
Last modified: 2009-08-15 18:40:50 UTC
I have included 4 files: source XML, XSL stylesheet, bad result from xsltproc, good result from other engine I think the problem revolves around the processing of the ACTIONgrid variable. Either the XPath assignment doesn't resolve into a proper nodeset, or the variable isn't properly resolved in the for-each of the GROUP[@type='ACTION'] template. ============= source XML ============= <?xml version="1.0"?> <XMLDATA> <RUNDATE>Wed Apr 4 23:00:55 2001 GMT</RUNDATE> <GROUP type="PRODUCT" name="Apple"> <GROUP type="ACTION" name="PICK"> <GROUP type="REC" name="Non-Recurring"> <ROW> <NUM>1</NUM> <PRODUCT>Apple</PRODUCT> <REC>Non-Recurring</REC> <SEGMENT>Birch</SEGMENT> <PREV>0</PREV> <AREV>50</AREV> <ACTION>PICK</ACTION> </ROW> </GROUP> </GROUP> <GROUP type="ACTION" name="EAT"> <GROUP type="REC" name="Non-Recurring"> <ROW> <NUM>6</NUM> <PRODUCT>Apple</PRODUCT> <REC>Non-Recurring</REC> <SEGMENT>Pine</SEGMENT> <PREV>0</PREV> <AREV>0</AREV> <ACTION>EAT</ACTION> </ROW> <ROW> <NUM>60</NUM> <PRODUCT>Apple</PRODUCT> <REC>Non-Recurring</REC> <SEGMENT>Elm</SEGMENT> <PREV>0</PREV> <AREV>0</AREV> <ACTION>EAT</ACTION> </ROW> <ROW> <NUM>2</NUM> <PRODUCT>Apple</PRODUCT> <REC>Non-Recurring</REC> <SEGMENT>Birch</SEGMENT> <PREV>0</PREV> <AREV>0</AREV> <ACTION>EAT</ACTION> </ROW> </GROUP> </GROUP> <GROUP type="ACTION" name="SQUEEZE"> <GROUP type="REC" name="Recurring"> <ROW> <NUM>7</NUM> <PRODUCT>Apple</PRODUCT> <REC>Recurring</REC> <SEGMENT>Pine</SEGMENT> <PREV>19250</PREV> <AREV>16.61</AREV> <ACTION>SQUEEZE</ACTION> </ROW> <ROW> <NUM>96</NUM> <PRODUCT>Apple</PRODUCT> <REC>Recurring</REC> <SEGMENT>Elm</SEGMENT> <PREV>220000</PREV> <AREV>11.76</AREV> <ACTION>SQUEEZE</ACTION> </ROW> <ROW> <NUM>6</NUM> <PRODUCT>Apple</PRODUCT> <REC>Recurring</REC> <SEGMENT>Birch</SEGMENT> <PREV>16500</PREV> <AREV>7.16</AREV> <ACTION>SQUEEZE</ACTION> </ROW> </GROUP> </GROUP> </GROUP> </XMLDATA> ===================== XSL Stylesheet =====================<?xml version = "1.0" encoding = "UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:variable name="ACTIONgrid" select="//GROUP[@type='REC' and not(@name=preceding::GROUP[@type='REC']/@name)]/@name<xsl:template match='/'> <html> <head> <title>Churn by Product</title> <style type="text/css"> .PROD {background-color:cyan} .PROD * {background-color:cyan} .ACT {background-color:green;font-weight:bold} .ACT * {background-color:green;font-weight:bold} .NR {background-color:yellow;color:blue} .NR * {background-color:yellow;color:blue} .RC {background-color:yellow;color:red} .RC * {background-color:yellow;color:red} </style> </head> <body> <h1><center>Churn by Product</center></h1> <table width="100%"> <tr> <td width="50%" align="left" valign="top"> Run Date: <xsl:value-of select="XMLDATA/RUNDATE"/><br/> Parameters: </td> <td align="right" valign="top"> <table><tr><th>Legend</th></tr><tr class="PROD"><td>Product</td></tr> <tr class="ACT"><td>Action</td></tr> <tr class="NR"><td>Non-Recurring</td></tr> <tr class="RC"><td>Recurring</td></tr> </table> </td> </tr> </table> <table align="center"><xsl:apply-templates select="/XMLDATA/GROUP"/></table> </body> </html> </xsl:template><xsl:template match="GROUP[@type='PRODUCT']"> <tr> <xsl:attribute name="class"> PROD </xsl:attribute> <td><xsl:value-of select='.//ROW[1]/PRODUCT'/></td> <td>Proj. Rev: <xsl:value-of select='sum(.//ROW/PREV)'/></td> <td>Actual Rev: <xsl:value-of select='sum(.//ROW/AREV)'/></td> </tr> <xsl:apply-templates select='GROUP'/> <tr> <xsl:attribute name="class"> PROD </xsl:attribute> </tr> </xsl:template><xsl:template match="GROUP[@type='ACTION']"> <xsl:variable name='grp' select='.'/> <tr> <xsl:attribute name="class"> ACT </xsl:attribute> <td><xsl:value-of select='.//ROW[1]/ACTION'/></td> <td>Proj. Rev: <xsl:value-of select='sum(.//ROW/PREV)'/></td> <td>Act. Rev: <xsl:value-of select='sum(.//ROW/AREV)'/></td> </tr> <tr> <xsl:for-each select='$ACTIONgrid'> <xsl:sort select='.'/> <td valign='top'> <xsl:apply-templates select='$grp/GROUP[@name=current()]'/> </td> </xsl:for-each> </tr> <tr> <xsl:attribute name="class"> ACT </xsl:attribute> </tr> </xsl:template> <xsl:template match="GROUP[@type='REC']"> <table> <tr> <xsl:attribute name="class"> <xsl:choose> <xsl:when test="@name='Recurring'">RC</xsl:when> <xsl:otherwise>NR</xsl:otherwise> </xsl:choose> </xsl:attribute> <td><xsl:value-of select='.//ROW[1]/REC'/></td> <td>Number: <xsl:value-of select='sum(.//ROW/NUM)'/></td> <td>Proj. Rev: <xsl:value-of select='sum(.//ROW/PREV)'/></td> <td>Act. Rev: <xsl:value-of select='sum(.//ROW/AREV)'/></td> </tr> <tr> <td>Segment</td> <td>Number</td> <td>Proj. Rev</td> <td>Act. Rev</td> </tr> <xsl:apply-templates select='ROW'/> <tr> <xsl:attribute name="class"> <xsl:choose> <xsl:when test="@name='Recurring'">RC</xsl:when> <xsl:otherwise>NR</xsl:otherwise> </xsl:choose> </xsl:attribute> </tr> </table> </xsl:template> <xsl:template match='ROW'> <tr> <xsl:apply-templates select='SEGMENT'/> <xsl:apply-templates select='NUM'/> <xsl:apply-templates select='PREV'/> <xsl:apply-templates select='AREV'/> </tr> </xsl:template> <xsl:template match='SEGMENT|NUM|PREV|AREV'> <td> <xsl:value-of select='.'/> </td> </xsl:template> </xsl:stylesheet> ============= Bad Result ============= <?xml version="1.0"?> <html><head><title>Churn by Product</title><style type="text/css"> .PROD {background-color:cyan} .PROD * {background-color:cyan} .ACT {background-color:green;font-weight:bold} .ACT * {background-color:green;font-weight:bold} .NR {background-color:yellow;color:blue} .NR * {background-color:yellow;color:blue} .RC {background-color:yellow;color:red} .RC * {background-color:yellow;color:red} </style></head><body><h1><center>Churn by Product</center></h1><table width="100%"><tr><td width="50%" align="left" valign="top"> Run Date: Wed Apr 4 23:00:55 2001 GMT<br/> Parameters: </td><td align="right" valign="top"><table><tr><th>Legend</th></tr><tr class="PROD"><td>Product</td></tr><tr class="ACT"><td>Action</td></tr><tr class="NR"><td>Non-Recurring</td></tr><tr class="RC"><td>Recurring</td></tr></table></td></tr></table><table align="center"><tr class=" PROD "><td>Apple</td><td>Proj. Rev: 255750</td><td>Actual Rev: 85.53</td></tr><tr class=" ACT "><td>PICK</td><td>Proj. Rev: 0</td><td>Act. Rev: 50</td></tr><tr><td valign="top"/><td valign="top"/></tr><tr class=" ACT "/><tr class=" ACT "><td>EAT</td><td>Proj. Rev: 0</td><td>Act. Rev: 0</td></tr><tr><td valign="top"/><td valign="top"/></tr><tr class=" ACT "/><tr class=" ACT "><td>SQUEEZE</td><td>Proj. Rev: 255750</td><td>Act. Rev: 35.53</td></tr><tr><td valign="top"/><td valign="top"/></tr><tr class=" ACT "/><tr class=" PROD "/></table></body></html> =========== Good Result =========== <html> <head> <META http-equiv="Content-Type" content="text/html"> <title>Churn by Product</title> <style type="text/css"> .PROD {background-color:cyan} .PROD * {background-color:cyan} .ACT {background-color:green;font-weight:bold} .ACT * {background-color:green;font-weight:bold} .NR {background-color:yellow;color:blue} .NR * {background-color:yellow;color:blue} .RC {background-color:yellow;color:red} .RC * {background-color:yellow;color:red} </style> </head> <body> <h1> <center>Churn by Product</center> </h1> <table width="100%"> <tr> <td width="50%" align="left" valign="top"> Run Date: Wed Apr 4 23:00:55 2001 GMT<br> Parameters: </td> <td align="right" valign="top"> <table> <tr> <th>Legend</th> </tr> <tr class="PROD"> <td>Product</td> </tr> <tr class="ACT"> <td>Action</td> </tr> <tr class="NR"> <td>Non-Recurring</td> </tr> <tr class="RC"> <td>Recurring</td> </tr> </table> </td> </tr> </table> <table align="center"> <tr class="PROD"> <td>Apple</td> <td>Proj. Rev: 255750</td> <td>Actual Rev: 85.53</td> </tr> <tr class="ACT"> <td>PICK</td> <td>Proj. Rev: 0</td> <td>Act. Rev: 50</td> </tr> <tr> <td valign="top"> <table> <tr class="NR"> <td>Non-Recurring</td> <td>Number: 1</td> <td>Proj. Rev: 0</td> <td>Act. Rev: 50</td> </tr> <tr> <td>Segment</td> <td>Number</td> <td>Proj. Rev</td> <td>Act. Rev</td> </tr> <tr> <td>Birch</td> <td>1</td> <td>0</td> <td>50</td> </tr> <tr class="NR"></tr> </table> </td> <td valign="top"></td> </tr> <tr class="ACT"></tr> <tr class="ACT"> <td>EAT</td> <td>Proj. Rev: 0</td> <td>Act. Rev: 0</td> </tr> <tr> <td valign="top"> <table> <tr class="NR"> <td>Non-Recurring</td> <td>Number: 68</td> <td>Proj. Rev: 0</td> <td>Act. Rev: 0</td> </tr> <tr> <td>Segment</td> <td>Number</td> <td>Proj. Rev</td> <td>Act. Rev</td> </tr> <tr> <td>Pine</td> <td>6</td> <td>0</td> <td>0</td> </tr> <tr> <td>Elm</td> <td>60</td> <td>0</td> <td>0</td> </tr> <tr> <td>Birch</td> <td>2</td> <td>0</td> <td>0</td> </tr> <tr class="NR"></tr> </table> </td> <td valign="top"></td> </tr> <tr class="ACT"></tr> <tr class="ACT"> <td>SQUEEZE</td> <td>Proj. Rev: 255750</td> <td>Act. Rev: 35.53</td> </tr> <tr> <td valign="top"></td> <td valign="top"> <table> <tr class="RC"> <td>Recurring</td> <td>Number: 109</td> <td>Proj. Rev: 255750</td> <td>Act. Rev: 35.53</td> </tr> <tr> <td>Segment</td> <td>Number</td> <td>Proj. Rev</td> <td>Act. Rev</td> </tr> <tr> <td>Pine</td> <td>7</td> <td>19250</td> <td>16.61</td> </tr> <tr> <td>Elm</td> <td>96</td> <td>220000</td> <td>11.76</td> </tr> <tr> <td>Birch</td> <td>6</td> <td>16500</td> <td>7.16</td> </tr> <tr class="RC"></tr> </table> </td> </tr> <tr class="ACT"></tr> <tr class="PROD"></tr> </table> </body> </html>
Could you check if libxslt-0.7.0 / libxml-2.3.6 solves the problem ? I wasn't able to run the test myself since the XSL stylesheet got mangled when added to the bugzilla database, resending it by mail will certainly help me chase the bug if it is still there. Daniel
The error was in the current() XSLT function implementation, it is fixed in CVS, checked the output after the fix with the bug reporter. Added the bug example to the libxslt regression tests, Daniel