Project

Profile

Help

Bug #4327

closed

Error SXST0067: No transmission filter available for parent::(document-node()|element())

Added by Martin Honnen over 4 years ago. Updated over 4 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Category:
Streaming
Sprint/Milestone:
-
Start date:
2019-10-01
Due date:
% Done:

0%

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

Description

In an attempt to run a stylesheet trying to split an input documents into chunks using streaming and Saxon 9.9.1.5 EE the processing is executed but then throws an error

Error SXST0067: No transmission filter available for parent::(document-node()|element())

The code is rather simple other than trying to use xsl:copy select=".." inside of the positional for-each-group:

<?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" exclude-result-prefixes="#all" version="3.0">

    <xsl:param name="chunk-size" as="xs:integer" select="500"/>

    <xsl:mode streamable="yes"/>
    <xsl:output indent="yes"/>

    <xsl:template match="/*">
        <xsl:for-each-group select="*" group-adjacent="(position() - 1) idiv $chunk-size">
            <xsl:result-document href="split-{position()}.xml">
                <xsl:copy select="..">
                    <xsl:copy-of select="current-group()"/>
                </xsl:copy>
            </xsl:result-document>
        </xsl:for-each-group>
    </xsl:template>

</xsl:stylesheet>

Input can be any XML with at least two nesting levels.

Workaround for me that works is using <xsl:element name="{name(..)}" namespace="{namespace-uri(..)}"> instead of the xsl:copy-of.

Actions #1

Updated by Michael Kay over 4 years ago

  • Status changed from New to In Progress

Reproduced as XSLT3 test si-group-063.

Actions #2

Updated by Michael Kay over 4 years ago

The spec at ยง19.8.4.12 has an example almost identical to this one and explains that it is not guaranteed streamable, so if we take it that the spec is right, we need to work out why we haven't reported a non-streamability error at compile time.

Actions #3

Updated by Michael Kay over 4 years ago

Saxon's implementation here does not follow the spec very closely. Saxon translates the expression <xsl:copy select="S">XX</xsl:copy> into <xsl:for-each select="S"><xsl:copy>XX</xsl:copy></xsl:for-each> and applies streamability analysis to the converted expression; as a result it does not have separate rules for the case of xsl:copy/@select in the way that the spec does. The expression <xsl:copy><xsl:copy-of select="current-group()"/></xsl:copy> emerges, reasonably enough, as grounded and consuming. But as such, I would expect it to be rejected as an operand of <xsl:for-each select=".."/>.

Actions #4

Updated by Michael Kay over 4 years ago

If we change the construct to

                <xsl:for-each select="..">
                    <xsl:copy>
                        <xsl:copy-of select="current-group()"/>
                    </xsl:copy>
                </xsl:for-each>

then streamability analysis fails with

XTSE3430: Template rule is declared streamable but it does not satisfy the streamability rules. 
  * The current-group() function is evaluated repeatedly

(which is not quite true, because select=".." actually selects a singleton, but never mind)

Why the difference?

In the case with an explicit for-each, the CurrentGroupCall instruction has the property "isInLoop" set at a fairly early stage of static analysis (well before streamability analysis proper).

In the case with an implicit for-each, the property is set false. In fact it is initially set to true, and then subsequently reset during template optimization; it is set to false because the for-each has been recognized as having a singleton select.

So the difference turns out to be a somewhat accidental consequence of the sequence of optimization events.

Actions #5

Updated by Michael Kay over 4 years ago

If we change the call on current-group() to simply ",", then the code as written fails

XTSE3430: Template rule is declared streamable but it does not satisfy the streamability rules. 
  * Operand {.} of {xsl:copy-of} reads the string value or typed value of a node in
  climbing posture (line 15)

and the failure is the same if we switch to an explicit xsl:for-each. This seems a more reasonable way to fail (although again, the message is not quite accurate: xsl:copy-of is absorbing, but it's not actually reading the string value or typed value of the node). This message arises when assessing CopyOf(.) - it fails simply because the context posture is climbing and the operand usage is absorption.

The difference between the select="." case and the select="current-group()" case is that in the former case, the posture of ",: is taken to be the context posture (climbing) whereas in the latter case, the context posture is ignored.

This comes down to the rule for streamability of current-group(): "The path in the construct tree that connects C to the sequence constructor forming the body of F is such that no child construct is a higher-order operand of its parent". The problem is that we are implementing this rule by looking at the "isInLoop" property, and in this particular case, which is a rarity we are within a higher-order operand that is not actually a loop.

The "isInLoop" property is used only for determining streamability, so we should be asking whether it's a higher-order operand instead.

The problem appears to be that the method operand.isEvaluatedRepeatedly() is being used as a proxy for being a higher-order operand. We have the data in the operand properties to distinguish the two cases, but we are not using it correctly.

Actions #6

Updated by Michael Kay over 4 years ago

  • Status changed from In Progress to Resolved
  • Applies to branch trunk added
  • Fix Committed on Branch 9.9, trunk added

Fixed by distinguishing Operand.isEvaluatedRepeatedly() from Operand.isHigherOrder(), and using the latter when assessing streamability of fn:current-group().

Actions #7

Updated by O'Neil Delpratt over 4 years ago

  • Status changed from Resolved to Closed
  • Fixed in Maintenance Release 9.9.1.6 added

Patch committed to the Saxon 9.9.1.6 maintenance release.

Please register to edit this issue

Also available in: Atom PDF