Project

Profile

Help

Bug #3281

closed

Getting wrong result when using streaming with for-each-group group-by and map variable inside to collect some data from current group

Added by Martin Honnen almost 7 years ago. Updated almost 7 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
Streaming
Sprint/Milestone:
-
Start date:
2017-06-14
Due date:
% Done:

100%

Estimated time:
Legacy ID:
Applies to branch:
9.7, 9.8
Fix Committed on Branch:
9.8
Fixed in Maintenance Release:
Platforms:

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

Also available in: Atom PDF