Actions
Bug #3883
closedXSLT 3 using xsl:merge to merge some files gives desired result with streaming and Saxon 9.8 EE but wrong result with duplicated elements with HE or with EE and streaming turned off
Start date:
2018-08-24
Due date:
% Done:
0%
Estimated time:
Legacy ID:
Applies to branch:
Fix Committed on Branch:
Fixed in Maintenance Release:
Platforms:
Description
I have the following XSLT 3 program
<?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"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
version="3.0">
<xsl:param name="input-uri" as="xs:string" select="'.'"/>
<xsl:param name="file-pattern" as="xs:string" select="'input*.xml'"/>
<xsl:param name="merge-select-expression" as="xs:string" static="yes" select="'*/*/*'"/>
<xsl:param name="xslt-pattern-to-add-file-name" as="xs:string" static="yes" select="'item'"/>
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template name="xsl:initial-template">
<xsl:merge>
<xsl:merge-source
for-each-source="uri-collection($input-uri || '?select=' || $file-pattern)"
_select="{$merge-select-expression}"
streamable="yes">
<xsl:merge-key select="true()"/>
</xsl:merge-source>
<xsl:merge-action>
<xsl:sequence select="let $group-tail := tail(current-merge-group()) return mf:construct-doc(., $group-tail)"/>
</xsl:merge-action>
</xsl:merge>
</xsl:template>
<xsl:template _match="{$xslt-pattern-to-add-file-name}">
<xsl:comment select="'Copied from ' || tokenize(document-uri(/), '/')[last()]"/>
<xsl:next-match/>
</xsl:template>
<xsl:function name="mf:construct-doc" as="document-node()">
<xsl:param name="first-node" as="node()"/>
<xsl:param name="nodes" as="node()*"/>
<xsl:apply-templates select="root($first-node)" mode="construct">
<xsl:with-param name="nodes" select="$nodes"/>
</xsl:apply-templates>
</xsl:function>
<xsl:mode name="construct" on-no-match="shallow-copy"/>
<xsl:template _match="{$merge-select-expression}" mode="construct">
<xsl:param name="nodes"/>
<xsl:apply-templates select="."/>
<xsl:apply-templates select="$nodes"/>
</xsl:template>
</xsl:stylesheet>
that is meant to be run with the -it
option to use xsl:merge
with a merge source taken from a uri-collection()
of some XML files in a folder to simply create new result file containing all nodes selected by _select="{$merge-select-expression}"
and additionally allow to mark result elements with a comment to where the file comes from.
Given to samples files input1.xml
and input2.xml
in the form
<root>
<items>
<item>
<foo>foo 1, file 1</foo>
<name>name 1, file 1</name>
</item>
<item>
<foo>foo 2, file 1</foo>
<name>name 2, file 1</name>
</item>
</items>
</root>
and
<root>
<items>
<item>
<foo>foo 1, file 2</foo>
<name>name 1, file 2</name>
</item>
<item>
<foo>foo 2, file 2</foo>
<name>name 2, file 2</name>
</item>
</items>
</root>
when I run it with Saxon 9.8.0.12 EE from the command line I get the wanted output:
<root>
<items><!--Copied from input1.xml-->
<item>
<foo>foo 1, file 1</foo>
<name>name 1, file 1</name>
</item>
<!--Copied from input1.xml-->
<item>
<foo>foo 2, file 1</foo>
<name>name 2, file 1</name>
</item>
<!--Copied from input2.xml-->
<item>
<foo>foo 1, file 2</foo>
<name>name 1, file 2</name>
</item>
<!--Copied from input2.xml-->
<item>
<foo>foo 2, file 2</foo>
<name>name 2, file 2</name>
</item>
</items>
</root>
However when run with Saxon 9.8.0.14 HE from the command line all elements are duplicated:
<root>
<items>
<!--Copied from input1.xml--> <item>
<foo>foo 1, file 1</foo>
<name>name 1, file 1</name>
</item>
<!--Copied from input1.xml-->
<item>
<foo>foo 2, file 1</foo>
<name>name 2, file 1</name>
</item>
<!--Copied from input2.xml-->
<item>
<foo>foo 1, file 2</foo>
<name>name 1, file 2</name>
</item>
<!--Copied from input2.xml-->
<item>
<foo>foo 2, file 2</foo>
<name>name 2, file 2</name>
</item>
<!--Copied from input1.xml--> <item>
<foo>foo 2, file 1</foo>
<name>name 2, file 1</name>
</item>
<!--Copied from input1.xml-->
<item>
<foo>foo 2, file 1</foo>
<name>name 2, file 1</name>
</item>
<!--Copied from input2.xml-->
<item>
<foo>foo 1, file 2</foo>
<name>name 1, file 2</name>
</item>
<!--Copied from input2.xml-->
<item>
<foo>foo 2, file 2</foo>
<name>name 2, file 2</name>
</item>
</items>
</root>
Please register to edit this issue
Actions