Bug #5013
closedsaxon:capture doesn't copy accumulator
100%
Description
I think I have found an issue with XSLT 3 streaming and an accumulator using saxon:capture
which I understand makes a snapshot()
available. Somehow that snapshot doesn't seem to copy another accumulator used (tested with EE 10.5 Java).
Sample 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:saxon="http://saxon.sf.net/"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:mode streamable="yes" on-no-match="shallow-skip" use-accumulators="#all"/>
<xsl:accumulator name="header-cats" as="xs:string*" initial-value="()" streamable="yes">
<xsl:accumulator-rule match="header-items/item/cat/text()" select="$value, string()"/>
</xsl:accumulator>
<xsl:accumulator name="capture-data" as="element()?" initial-value="()" streamable="yes">
<xsl:accumulator-rule match="data-items/foo" phase="end" saxon:capture="yes" select="."/>
</xsl:accumulator>
<xsl:template match="foo">
<xsl:copy-of select="accumulator-after('capture-data')[not(cat = trace(accumulator-before('header-cats')))]"/>
</xsl:template>
</xsl:stylesheet>
When run against the input sample show below I get the output
*: empty sequence
*: empty sequence
<foo>
<value>foo 1</value>
<cat>cat4</cat>
</foo>
<foo>
<value>foo 2</value>
<cat>cat2</cat>
</foo>
Input:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<header-items>
<item>
<id>h1</id>
<cat>cat1</cat>
</item>
<item>
<id>h2</id>
<cat>cat2</cat>
</item>
<item>
<id>h3</id>
<cat>cat3</cat>
</item>
</header-items>
<data-items>
<foo>
<value>foo 1</value>
<cat>cat4</cat>
</foo>
<foo>
<value>foo 2</value>
<cat>cat2</cat>
</foo>
</data-items>
</root>
When I use snapshot
explicitly, as in
<?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:saxon="http://saxon.sf.net/"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:mode streamable="yes" on-no-match="shallow-skip" use-accumulators="#all"/>
<xsl:accumulator name="header-cats" as="xs:string*" initial-value="()" streamable="yes">
<xsl:accumulator-rule match="header-items/item/cat/text()" select="$value, string()"/>
</xsl:accumulator>
<xsl:template match="foo">
<xsl:copy-of select="snapshot()[not(cat = trace(accumulator-before('header-cats')))]"/>
</xsl:template>
</xsl:stylesheet>
I get the output
* [1]: xs:string: cat1
* [2]: xs:string: cat2
* [3]: xs:string: cat3
* [1]: xs:string: cat1
* [2]: xs:string: cat2
<foo>
<value>foo 1</value>
<cat>cat4</cat>
</foo>
so there the other accumulator header-cats
seems to be copied.
I supposed that should also happen for the saxon:capture
use.
Updated by Michael Kay over 3 years ago
Took me a while to understand what's going on here...
I can confirm that the snapshot made implicitly by the saxon:capture="yes" setting does NOT copy the values of other accumulators defined on the copied nodes.
I propose to change the documentation to clarify this: the logic for fixing it would be pretty tortuous.
Updated by Michael Kay over 3 years ago
- Status changed from New to Resolved
- Assignee set to Michael Kay
- Applies to branch trunk added
- Fix Committed on Branch 10, trunk added
Resolved with a clarification to the documentation of saxon:capture.
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