Bug #1971
closedBurst-mode streaming not working as documented
100%
Description
I'm trying out some of the streaming features using Saxon 9.5.1.2 EE bundled with Oxygen 15.1, build 2013110816 and I'm getting an error from the first example for "burst-mode streaming" provided in the documentation here: http://www.saxonica.com/documentation/sourcedocs/streaming/burst-mode-streaming.html
When I use the example code I get the following error:
Engine name: Saxon-EE 9.5.1.2
Severity: fatal
Description: SXST0060: Expression xsl:apply-templates is free-ranging * There is an xsl:apply-templates instruction using a non-streamable mode
Start location: 9:0
URL: http://www.saxonica.com/html/documentation/javadoc/net/sf/saxon/trans/SaxonErrorCode.html#SXST0060
I've attached the sample stylesheet and source document I'm using. Am I missing something?
Files
Updated by Michael Kay almost 11 years ago
- Category set to Streaming
- Assignee set to Michael Kay
- Priority changed from Low to Normal
Thanks for reporting this.
Unfortunately there's a major bug in the streamability rules of the July 2012 XSLT 3.0 draft, which Saxon has slavishly copied. This is fixed in the Dec 2013 draft, and in the development branch of Saxon, so that this example once again works. The bug is that the streamability analysis in the 2012 draft assumes that when an expression is consuming (select="copy-of(*/employee)" then it is returning streamed nodes, and of course this isn't the case - in fact that's exactly why copy-of() was introduced.
The question is, what to do about it. The run-time machinery in Saxon 9.5 is perfectly capable of streaming this expression, the fault is in the static analysis. I think that retrofitting the whole machinery of the Dec 2013 streamability analysis into the 9.5 branch is probably too disruptive for a maintenance release, so I will look at whether there is some more localized patch possible.
Meanwhile, I think you are probably best off using the Saxon-specific saxon:stream() interface: that is, replace the call on xsl:stream by
<xsl:sequence select="saxon:stream(doc('employees.xml')/*/employee)"/>
Note that you shouldn't really be using match="/" as the entry point to a streamed stylesheet: that would mean you have to supply a document as input, and if you supply employees.xml then it will be built as a tree in memory. Better to use an entry point with name="main" and then it:main (and no -s) on the command line invocation - or whatever the equivalent is in oXygen.
Updated by Michael Kay almost 11 years ago
- Status changed from New to Resolved
Note there is another problem with this example: copy-of(/employee) does not work because in the July 2012 draft, and therefore in Saxon 9.5, copy-of only accepts a single item as its argument. So it has to be rewritten as select="/employee/copy-of(.)". With this change, and with a few small patches, I have managed to make this example work; however the changes probably don't fix the problem in other similar circumstances. The changes are:
a) special-case the rules for apply-templates in the case where the argument is a call to the copy-of() function.
b) change the "syntactic context" of the argument of copy-of() to "node value context". This is equivalent to setting operand usage = absorption in the language of the Dec 2013 spec.
c) change the syntactic context of the argument of a cardinality checking expression (inserted automatically by the parser) to "inherited" (operand usage = transmission in the newer spec)
These changes are being committed to subversion and will appear in the next maintenance release assuming they cause no regression.
Updated by O'Neil Delpratt almost 11 years ago
- Status changed from Resolved to Closed
- % Done changed from 0 to 100
- Fixed in version set to 9.5.1.4
Bug fix applied in Saxon maintenance release 9.5.1.4
Updated by Eduard Porosnicu over 10 years ago
- Assignee changed from Michael Kay to O'Neil Delpratt
I am not sure what 'fixed in version 9.5.1.4' means. Is it now working as documented on the saxonica Web site http://www.saxonica.com/documentation/sourcedocs/streaming/burst-mode-streaming.html?
Updated by Michael Kay over 10 years ago
We fixed the code, but we haven't fixed the errors noted in the documentation yet. As described above, you have to change it to select="/employee/copy-of(.)".
Updated by Eduard Porosnicu over 10 years ago
I am using SaxonEE 9-5-1-6J and it does not seem to work. If I include the following in a test XSLT
<xsl:stream href='employees.xml'>
<xsl:apply-templates select="/employee/copy-of(.)"/>
</xsl:stream>
I get the following error:
Warning: at xsl:stream on line 10 column 36 of ExtractEmployeeByID.xslt:
The body of the xsl:stream instruction is not guaranteed streamable according to W3C rules
-
Root expression '/' is free-ranging
-
There is an xsl:apply-templates instruction using a non-streamable mode
Anyhow, it is not critical. It works well with the Saxon-specific saxon:stream() interface.
Updated by Michael Kay over 10 years ago
- Assignee changed from O'Neil Delpratt to Michael Kay
The implementation of xsl:stream in Saxon 9.5 is rather limited, mainly because the spec has moved on a long way since 9.5 was released, but also because at that time we only had a rather limited number of test cases (about 200: it's now probably up to 2000).
The restriction on path expressions starting with "/" was in the W3C spec at the time but has since been lifted, provided the context item is statically known to be a document node. As a workaround, simply remove the unnecessary leading "/"/
The use of apply-templates in a mode that is not declared streamable looks like an error in your stylesheet, not in Saxon.
As you say, however, sticking to burst mode streaming (that is. saxon:stream) is probably the prudent approach for the time being if it meets your needs.
Please register to edit this issue