Bug #3281
closedGetting wrong result when using streaming with for-each-group group-by and map variable inside to collect some data from current group
100%
Description
I am trying to test whether the grouping examples in the XSLT 3.0 spec can be converted to use streaming, I have managed to convert an example so that is passes the streamability analyis in Saxon 9.8 EE, however, unfortunately the result I then get is wrong and different to running the code without streaming.
Here are the details, the input sample is
<?xml version="1.0" encoding="UTF-8"?>
<cities>
<city name="Milano" country="Italia" pop="5"/>
<city name="Paris" country="France" pop="7"/>
<city name="München" country="Deutschland" pop="4"/>
<city name="Lyon" country="France" pop="2"/>
<city name="Venezia" country="Italia" pop="1"/>
</cities>
to convert the original code
<xsl:for-each-group select="cities/city" group-by="@country">
<tr>
<td><xsl:value-of select="position()"/></td>
<td><xsl:value-of select="current-grouping-key()"/></td>
<td>
<xsl:for-each select="current-group()/@name">
<xsl:sort select="."/>
<xsl:if test="position() ne 1">, </xsl:if>
<xsl:value-of select="."/>
</xsl:for-each>
</td>
<td><xsl:value-of select="sum(current-group()/@pop)"/></td>
</tr>
</xsl:for-each-group>
to a streamable example I have removed the sort and then tried to use a map to store the result of the list of name attributes and of the sum:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math" exclude-result-prefixes="xs math"
version="3.0">
<xsl:param name="STREAMABLE" static="yes" as="xs:boolean" select="true()"/>
<xsl:mode _streamable="{$STREAMABLE}"/>
<xsl:output method="html" indent="yes"/>
<xsl:template match="/">
<html>
<head>
<title>Population grouped by country</title>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="cities">
<table>
<tr>
<th>Position</th>
<th>Country</th>
<th>City List</th>
<th>Population</th>
</tr>
<xsl:fork>
<xsl:for-each-group select="city" group-by="@country">
<tr>
<td>
<xsl:value-of select="position()"/>
</td>
<td>
<xsl:value-of select="current-grouping-key()"/>
</td>
<xsl:variable name="data"
select="map { 'cities' : current-group()/@name/string(), 'pop-sum' : sum(current-group()/@pop) }"/>
<td>
<xsl:value-of select="$data?cities" separator=", "/>
</td>
<td>
<xsl:value-of select="$data?pop-sum"/>
</td>
</tr>
</xsl:for-each-group>
</xsl:fork>
</table>
</xsl:template>
</xsl:stylesheet>
When I run that with Saxon-EE 9.8.0.1J from the command line I get the following odd result, with wrong data and various duplicated td
elements:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Population grouped by country</title>
</head>
<body>
<table>
<tr>
<th>Position</th>
<th>Country</th>
<th>City List</th>
<th>Population</th>
</tr>
<tr>
<td>1</td>
<td>Italia</td>
<td>1</td>
<td>Italia</td>
<td>1</td>
<td>Italia</td>
<td>Milano</td>
<td>5</td>
</tr>
<tr>
<td>2</td>
<td>France</td>
<td>2</td>
<td>France</td>
<td>2</td>
<td>France</td>
<td>Paris</td>
<td>7</td>
</tr>
<tr>
<td>3</td>
<td>Deutschland</td>
<td>3</td>
<td>Deutschland</td>
<td>3</td>
<td>Deutschland</td>
<td>München</td>
<td>4</td>
</tr>
</table>
</body>
</html>
When I turn of streaming by setting the parameter STREAMABLE=0
on the command line I get the correct, wanted result:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Population grouped by country</title>
</head>
<body>
<table>
<tr>
<th>Position</th>
<th>Country</th>
<th>City List</th>
<th>Population</th>
</tr>
<tr>
<td>1</td>
<td>Italia</td>
<td>Milano, Venezia</td>
<td>6</td>
</tr>
<tr>
<td>2</td>
<td>France</td>
<td>Paris, Lyon</td>
<td>9</td>
</tr>
<tr>
<td>3</td>
<td>Deutschland</td>
<td>München</td>
<td>4</td>
</tr>
</table>
</body>
</html>
9.7 EE when run with streaming also gives a wrong result, it does not output duplicated td
elements but the data in the table cells coming from the map is wrong:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Population grouped by country</title>
</head>
<body>
<table>
<tr>
<th>Position</th>
<th>Country</th>
<th>City List</th>
<th>Population</th>
</tr>
<tr>
<td>1</td>
<td>Italia</td>
<td>Milano</td>
<td>0</td>
</tr>
<tr>
<td>2</td>
<td>France</td>
<td>Paris</td>
<td>0</td>
</tr>
<tr>
<td>3</td>
<td>Deutschland</td>
<td>München</td>
<td>0</td>
</tr>
</table>
</body>
</html>
I have also tried a different approach to using a map by nesting another @xsl:fork@, unfortunately, that too does not give the right result when using streaming with Saxon 9.8. I will post that later as a separate issue.
Please register to edit this issue