I have a big XML file (6 GB) with this kind of tree:
<Report>
<Document>
<documentType>E</documentType>
<person>
<firstname>John</firstname>
<lastname>Smith</lastname>
</person>
</Document>
<Document>
[...]
</Document>
<Document>
[...]
</Document>
[... there are a lot of Documents]
</Report>
So I used the new XSLT 3.0 streaming feature, with Saxon 9.6 EE.
I don't want to have the streaming constrains once in a Document. This is why I tried to used copy-of().
I think that, what I want to do, is very close to the "burst mode" that is described here: http://saxonica.com/documentation/html/sourcedocs/streaming/burst-mode-streaming.html
Here is my XSLT style sheet:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
<xsl:mode streamable="yes" />
<xsl:template match="/">
GLOBAL HEADER
<xsl:for-each select="/Report/Document/copy-of()" >
DOC HEADER
documentType: <xsl:value-of select="documentType"/>
person/firstname: <xsl:value-of select="person/firstname"/>
<xsl:call-template name="fnc1"/>
DOC FOOTER
</xsl:for-each>
GLOBAL FOOTER
</xsl:template>
<xsl:template name="fnc1">
documentType again: <xsl:value-of select="documentType"/>
</xsl:template>
</xsl:stylesheet>
In a sense it works because with the copy-of() I'm able to use several xsl:value-of directly in the for-each (like in this question). (Otherwise I have this error * There are at least two consuming operands: {xsl:value-of} on line 8, and {xsl:value-of} on line 9)
But I still have streaming constrains because <xsl:call-template name="fnc1"/> creates this error:
Error at xsl:template on line 4 column 25 of stylesheet.xsl:
XTSE3430: Template rule is declared streamable but it does not satisfy the streamability rules.
* xsl:call-template is not streamable in this Saxon release
Stylesheet compilation failed: 1 error reported
So my question is: how to do partial streaming (Documents are loaded one by one but fully) in order to be able to use call-template (and other apply-templates) in a Document?
Thank you for your help!
I think call-template should be streamable when the context item is grounded (ie. not a streamed node), so I'll treat this as a bug. Meanwhile a workaround might be to declare fnc1 as
<xsl:template name="fnc1" mode="fnc1" match="Document"/>
and call it as
<xsl:apply-templates select="." mode="fnc1"/>
Alternatively, replace the template with a function and supply the context item as an explicit argument.
You can track the bug here:
https://saxonica.plan.io/issues/2171
Although we don't claim 100% conformance with the XSLT 3.0 specification yet, we'll treat any unnecessary departures in the 9.6 release as bugs unless fixing them would destabilize the product.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With