for-each-group context not being preserved over context-altering steps
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.
calls to this added to several
Changes committed to Saxon-JS code branch, but issue left open for other cases
#1 Updated by John Lumley almost 2 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="mode.name" select="current-grouping-key()"/> <xsl:for-each select="$d[@name = $mode.name]"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:copy-of select="current-group()"/> </xsl:copy> </xsl:for-each>...
$mode.name 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 @$mode.name@, 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.
Please register to edit this issue