Project

Profile

Help

Should array { current-group() } be streamable?

Added by Martin Honnen over 3 years ago

In finding variants of the code in https://saxonica.plan.io/issues/5035 I tried to use an array as the container for streamed nodes, not being sure what should and would happen.

Saxon EE 10.5 Java tells me it should be streamable but it has no watch; the code

<?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:mf="http://example.com/mf"
    exclude-result-prefixes="#all">
    
    <xsl:function name="mf:group-into-sequence-of-arrays" as="array(*)*" visibility="public" streamability="absorbing">
        <xsl:param name="items" as="item()*"/>
        <xsl:param name="chunk-size" as="xs:integer"/>
        <xsl:for-each-group select="$items" group-adjacent="(position() - 1) idiv $chunk-size">
            <xsl:sequence select="array { current-group() }"/>
        </xsl:for-each-group>
    </xsl:function>
    
    <xsl:template match="/*">
        <xsl:copy>
            <xsl:iterate select="mf:group-into-sequence-of-arrays(*, 3)">
                <chunk index="{position()}">
                    <xsl:sequence select="?*"/>
                </chunk>
            </xsl:iterate>
        </xsl:copy>
    </xsl:template>
    
    <xsl:output indent="yes"/>
    
</xsl:stylesheet>

gives

Error in xsl:for-each-group/@select on line 11 column 96 of array-test1.xsl:
  SXST0067  Component cannot be streamed, although it is guaranteed streamable according to
  W3C rules. No watch implemented for CurrentGroupCall
Errors were reported during stylesheet compilation

Then I tried to find in the spec whether an array is supposed to be allowed to contain streamed nodes and https://www.w3.org/TR/xslt-30/#streaming-other-types clearly says:

The rules for creating maps and arrays are designed to ensure that the entries in a map, and the members of an array, cannot contain nodes from a streamed document.

So based on that I guess the code above should not pass the streamability analysis.

Can't find array {}, however, in the formal streamability rules.

Input can be any with at least two levels of elements e.g.

<?xml version="1.0" encoding="utf-8"?>
<root>
    <item>item 01</item>
    <item>item 02</item>
    <item>item 03</item>
    <item>item 04</item>
    <item>item 05</item>
    <item>item 06</item>
    <item>item 07</item>
    <item>item 08</item>
    <item>item 09</item>
    <item>item 10</item>
    <item>item 11</item>
    <item>item 12</item>
    <item>item 13</item>
    <item>item 14</item>
    <item>item 15</item>
    <item>item 16</item>
    <item>item 17</item>
    <item>item 18</item>
    <item>item 19</item>
    <item>item 20</item>
    <item>item 21</item>
    <item>item 22</item>
    <item>item 23</item>
</root>

Replies (3)

Please register to reply

RE: Should array { current-group() } be streamable? - Added by Martin Honnen over 3 years ago

I have now found some more formal definition of array { } and streamability, https://www.w3.org/TR/xslt-30/#classifying-expressions defines CurlyArrayConstructor [–,75] array{N, N, ...} where the N stands for "navigation" (https://www.w3.org/TR/xslt-30/#dt-navigation): "An operand usage of navigation indicates that the construct may navigate freely from the supplied node to other nodes in the same tree, in a way that is not constrained by the streamability rules.".

RE: Should array { current-group() } be streamable? - Added by Martin Honnen over 3 years ago

Based on further reading I think the declaration of the streamability of array { } as array {N, N, ... } should ensure that the attempt to use array { current-group() } where current-group() is built during streaming should lead to a failed streamability analysis as streamed nodes are selected in a context that allows arbitrary navigation. Error with similar construct raised by Saxon seems to be XTSE3430.

Any comments?

RE: Should array { current-group() } be streamable? - Added by Michael Kay over 3 years ago

Arrays are not well covered in the streamability rules in the spec, because arrays were only introduced in XP31, and the XSLT30 spec works primarily with XP30. Although many constructs involving arrays could potentially be streamable, the decision was made not to delay the spec by working that through; and more to the point, Saxon doesn't have any support for streaming of arrays. In fact, Saxon doesn't even do any pipelining of arrays: any expression that evaluates to an array will physically materialize the array in memory. (Though we do, in 10.x, use functional data structures (an immutable trie) that allows different arrays to share the storage for shared subarrays).

    (1-3/3)

    Please register to reply