Project

Profile

Help

Streamability of accumulator-after in select expression of accumulator-rule with phase=end

Added by Martin Honnen over 4 years ago

The section https://www.w3.org/TR/xslt-30/#streamability-fn-accumulator-after of the XSLT 3 spec when detailing the streamability of the accumulator-after function says under point 5:

If the function call is contained in the select expression or contained sequence constructor of an xsl:accumulator-rule specifying phase="end", then it is motionless.

That way I would expect to be able to call that function in an accumulator-rule with phase="end":

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    expand-text="yes"
    exclude-result-prefixes="#all">
    
    <xsl:mode streamable="yes" on-no-match="shallow-copy" use-accumulators="#all"/>
    
    <xsl:accumulator name="header-id" streamable="yes" as="xs:integer?" initial-value="()">
        <xsl:accumulator-rule match="header-item/id/text()" select="xs:integer(.)"/>
    </xsl:accumulator>
    
    <xsl:accumulator name="header-value" streamable="yes" as="xs:string?" initial-value="()">
        <xsl:accumulator-rule match="header-item/value/text()" select="string()"/>
    </xsl:accumulator>
    
    <xsl:accumulator name="header-map" streamable="yes" as="map(xs:integer, xs:string)" initial-value="map{}">
        <xsl:accumulator-rule match="header-item"
          phase="end"
          select="map:put($value, accumulator-after('header-id'), accumulator-after('header-value'))"/>
    </xsl:accumulator>
    
    <xsl:template match="header"/>
    
    <xsl:template match="item/header-ref">
        <header-value>{accumulator-before('header-map')(xs:integer(@idref))}</header-value>
    </xsl:template>
    
</xsl:stylesheet>

However, Saxon 9.9.1.2 EE (current latest Saxon 9 EE version available in oXygen) rejects that stylesheet with

The xsl:accumulator-rule/@select expression (or contained sequence constructor) for a streaming accumulator must be grounded and motionless. A call to accumulator-after() is consuming when there are no preceding consuming instructions

Is Saxon not implementing that rule 5 I cited or does it not apply to the above example for some other parts of the spec?

Sample input file would be

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <header>
        <header-item>
            <id>1</id>
            <value>header 1</value>
        </header-item>
        <header-item>
            <id>2</id>
            <value>header 2</value>
        </header-item>       
    </header>
    <body>
        <items>
            <item>
                <id>i1</id>
                <header-ref idref="1"/>
            </item>
        </items>
    </body>
</root>

Replies (2)

RE: Streamability of accumulator-after in select expression of accumulator-rule with phase=end - Added by Michael Kay over 4 years ago

I've raised this as issue #4293 so that it doesn't get forgotten. I think you are right that the relevant streamability rule for accumulator-after is not implemented.

    (1-2/2)

    Please register to reply