Bug #5035
closedSXST0067 Component cannot be streamed, although it is guaranteed streamable according to W3C rules. No watch implemented for locVarRef
100%
Description
I was trying to be creative and tried to write a generic function to use positional grouping and streaming, the code runs fine without streaming but gives the error
SXST0067 Component cannot be streamed, although it is guaranteed streamable according to
W3C rules. No watch implemented for locVarRef
when trying to compile and run the stylesheet.
Sample code inline and attached:
<?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"
xmlns:ex="http://example.com/ex"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:function name="mf:group-chunks" as="item()*" streamability="absorbing">
<xsl:param name="items" as="item()*"/>
<xsl:param name="chunk-size" as="xs:integer"/>
<xsl:param name="handle-chunk" as="function(item()*) as item()*"/>
<xsl:for-each-group select="$items" group-adjacent="(position() - 1) idiv $chunk-size">
<xsl:sequence select="$handle-chunk(current-group())"/>
</xsl:for-each-group>
</xsl:function>
<xsl:function name="ex:wrap-rows" as="element()" streamability="absorbing">
<xsl:param name="group" as="element()*"/>
<xsl:param name="wrapper-name" as="xs:QName"/>
<xsl:element name="{$wrapper-name}" namespace="{namespace-uri-from-QName($wrapper-name)}">
<xsl:sequence select="$group"/>
</xsl:element>
</xsl:function>
<xsl:output method="xml" indent="yes"/>
<xsl:mode streamable="yes"/>
<xsl:template match="root">
<xsl:copy>
<xsl:sequence select="mf:group-chunks(item, 3, ex:wrap-rows(?, QName((), 'chunk')))"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:next-match/>
<xsl:comment xmlns:saxon="http://saxon.sf.net/">Run with {system-property('xsl:product-name')} {system-property('xsl:product-version')} {system-property('Q{http://saxon.sf.net/}platform')}</xsl:comment>
</xsl:template>
</xsl:stylesheet>
Sample input:
<?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>
Full output with Saxon EE 10.5 Java:
Saxon-EE 10.5J from Saxonica
Java version 1.8.0_272
Using license serial number Vxxxxx
Error on line 22 column 99 of passing-current-group-to-function-test1.xsl:
SXST0067 Component cannot be streamed, although it is guaranteed streamable according to
W3C rules. No watch implemented for locVarRef
Errors were reported during stylesheet compilation
Files
Updated by Martin Honnen over 3 years ago
So far the only way I got a (partially?) streaming solution was by replacing
<xsl:sequence select="$handle-chunk(current-group())"/>
with
<xsl:sequence select="$handle-chunk(current-group()!copy-of())"/>
Updated by Michael Kay over 3 years ago
- Status changed from New to In Progress
Reproduced as XSLT test case su-absorbing-301
Updated by Michael Kay over 3 years ago
I think this test case is doomed to failure under the rules in ยง19.8.8.11 for dynamic function calls: The operands to a dynamic function call have usage navigation, therefore a dynamic call that supplies current-group() as an argument, where the group contains streamed nodes, should fail.
However, that isn't why it is failing. It's tripping up earlier trying to construct an inversion for function ex:wrap-rows
which is quite independent of the fact that the function is called dynamically. We can demonstrate this by replacing the dynamic function call with a static function call:
<xsl:function name="mf:group-chunks" as="item()*" 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="ex:wrap-rows(current-group(), QName((), 'chunk'))"/>
</xsl:for-each-group>
</xsl:function>
(and dropping the third argument in the call of mf:group-chunks).
Updated by Michael Kay over 3 years ago
At the code level, the problem is that VariableReferenceAdjunct
does not implement the method getWatchMaker()
, which means it picks up the default implementation in the superclass StreamingAdjunct
, which throws the observed error when the posture is striding or crawling. (It is striding in this case).
So the question is, what should the missing method VariableReferenceAdjunct.getWatchMaker()
actually do.
At this point I have to confess that I am less familiar with the intricacies of this very complex code than I was a few years ago.
Updated by Michael Kay over 3 years ago
- Status changed from In Progress to Resolved
- Applies to branch trunk added
- Fix Committed on Branch 10, trunk added
The problem is solved by making VariableReferenceAdjunct
extend CopyOfAdjunct
, thus inheriting its getWatchMaker
method.
Updated by O'Neil Delpratt about 3 years ago
- Status changed from Resolved to Closed
- % Done changed from 0 to 100
- Fixed in Maintenance Release 10.6 added
Bug fix applied in the Saxon 10.6 maintenance release
Please register to edit this issue