Bug #2945


for-each-group context not being preserved over context-altering steps

Added by John Lumley over 7 years ago. Updated almost 7 years ago.

Start date:
Due date:
% Done:


Estimated time:
Applies to JS Branch:
Fix Committed on JS Branch:
Fixed in JS Release:
SEF Generated with:
Contact person:
Additional contact persons:


Situations which alter local context, such as indexed filtering or xsl:for-each@, do not preserve any inherited grouping context, which is only altered by @xsl:for-each-group@. Thus @current-group() and current-grouping-key() can fail or be erroneous.

  • preserveGrouping() added to transform.Context

  • calls to this added to several Expr steps.

Changes committed to Saxon-JS code branch, but issue left open for other cases

Actions #1

Updated by John Lumley over 7 years ago

An additional and harder problem occurs with variables within the for-each-group sequence constructor that reference group properties (@current-grouping-key()@, @current-group()@, @position()@).


<xsl:for-each-group select="$p" group-by="@mode">
    <xsl:variable name="" select="current-grouping-key()"/>
    <xsl:for-each select="$d[@name = $]">
            <xsl:copy-of select="@*"/>
            <xsl:copy-of  select="current-group()"/>

the reference $ is being bound to the key for the last group, for all the groups. It appears that the closure for the let of each group retains the varRef for @$, but the varying context for each group isn't part of the closure, and the variable slot bound to that variable now has the constant-valued key for the last group. Hence when the iterators across the set of groups are executed, they all use variable bindings that were computed for the last group.

This appears to be the case for for all three of the group-variable properties.

Note that the properties themselves are retained (i.e. current-grouping-key() does vary) - it's the closure through the let (where the variable is evaluated completely and (over-)written to a value slot) and the subsequent interpolation through varRef after all groups have been formed that causes the problem.

It might imply that within group contexts, with variables being bound to group-variable properties, let cannot be evaluated (i.e. replaced by the evaluation of the content) during the group formation stage.

Actions #2

Updated by John Lumley over 7 years ago

  • Status changed from New to Resolved

Solution chosen is to evaluate the group sequence constructors eagerly and return an iteration over the whole group sequence concatenation at the end of @Compare.grouping()@. Changes applied to Saxon-JS code branch

Actions #3

Updated by Debbie Lockett over 7 years ago

  • Status changed from Resolved to Closed
  • % Done changed from 0 to 100
  • Found in version set to 0.9
  • Fixed in version set to 0.9.1

Bug fix applied in the Saxon-JS 0.9.1 beta release.

Actions #4

Updated by Community Admin almost 7 years ago

  • Fixed in JS Release set to Saxon-JS 0.9.1
  • Applies to JS Branch 0.9 added
  • Fix Committed on JS Branch 0.9 added
Actions #5

Updated by Debbie Lockett almost 7 years ago

  • Description updated (diff)
  • Applies to branch deleted (9.8)

Please register to edit this issue

Also available in: Atom PDF Tracking page