Merge
authorMichael Kay <mike@saxonica.com>
Mon, 03 Sep 2018 00:05:16 +0100
changeset 1885 c95de77a4228
parent 1874 5e4b71cc6795 (current diff)
parent 1884 86f29c06b4b4 (diff)
child 1886 5101619186ad
Merge
tests/misc/docbook/_docbook-test-set.xml
--- a/tests/attr/validation/_validation-test-set.xml	Fri Jul 20 13:15:12 2018 +0100
+++ b/tests/attr/validation/_validation-test-set.xml	Mon Sep 03 00:05:16 2018 +0100
@@ -389,6 +389,24 @@
          <error code="XTSE0020"/>
       </result>
    </test-case>
+   
+   <test-case name="validation-0111">
+      <description>
+         Validation of xsl:document with a document-node test
+      </description>
+      <created by="Michael Kay" on="2018-08-20"/>
+      <environment ref="validation-01"/>
+      <dependencies>
+         <spec value="XSLT20+"/>
+         <feature value="schema_aware" satisfied="true"/>
+      </dependencies>
+      <test>
+         <stylesheet file="validation-0111.xsl"/>
+      </test>
+      <result>
+         <error code="XTTE0505"/>
+      </result>
+   </test-case>
 
    <test-case name="validation-0201">
       <description>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/attr/validation/validation-0111.xsl	Mon Sep 03 00:05:16 2018 +0100
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
+  
+<!-- Purpose: test push-mode validation (in Saxon) against a document node test.-->
+  
+  <xsl:variable name="data">
+    <one>
+      <two>
+        <three>3</three>
+      </two>
+    </one>
+  </xsl:variable>
+
+   <xsl:template match="/">
+      <out>
+        <xsl:call-template name="content"/>
+      </out>
+   </xsl:template>
+  
+   <xsl:template name="content" as="document-node(element(four))">
+     <xsl:document>
+       <xsl:apply-templates select="$data/*"/>
+     </xsl:document>
+   </xsl:template>
+</xsl:transform>
--- a/tests/fn/key/_key-test-set.xml	Fri Jul 20 13:15:12 2018 +0100
+++ b/tests/fn/key/_key-test-set.xml	Mon Sep 03 00:05:16 2018 +0100
@@ -1798,4 +1798,21 @@
          <assert>/out = "Hot July brings cooling showers, Apricots and gillyflowers."</assert>
       </result>
    </test-case>
+   
+   <test-case name="key-097">
+      <description>Composite key. Saxon problem raised at https://saxonica.plan.io/boards/3/topics/7274?pn=1</description>
+      <created by="Michael Kay after Martin Honnen" on="2018-07-28"/>
+      <environment>
+         <source role="." file="key097.xml"/>
+      </environment>
+      <dependencies>
+         <spec value="XSLT30+"/>
+      </dependencies>
+      <test>
+         <stylesheet file="key-097.xsl"/>
+      </test>
+      <result>
+         <assert>count(/Message2/Response/CE) = 2</assert>
+      </result>
+   </test-case>
 </test-set>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/fn/key/key-097.xsl	Mon Sep 03 00:05:16 2018 +0100
@@ -0,0 +1,26 @@
+<?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"
+    exclude-result-prefixes="xs"
+    version="3.0">
+    
+    <xsl:mode on-no-match="shallow-copy"/>
+    
+    <xsl:key name="map" match="Message1/Response/CE//*[action = 'New']" composite="yes">
+        <xsl:sequence select="ancestor::CE/id"/>
+        <xsl:sequence select="node-name()"/>
+        <xsl:variable name="pos" as="xs:integer">
+            <xsl:number/>
+        </xsl:variable>
+        <xsl:sequence select="$pos"/>
+    </xsl:key>
+    
+    <xsl:template match="Messages">
+        <xsl:apply-templates select="Message2"/>
+    </xsl:template>
+    
+    <xsl:template match="Message2/Response/CE//*[key('map', (ancestor::CE/id, node-name(), count((., preceding-sibling::*[node-name() = node-name(current())]))))]">
+        <xsl:copy-of select="key('map', (ancestor::CE/id, node-name(), count((., preceding-sibling::*[node-name() = node-name(current())]))))"/>
+    </xsl:template>
+    
+</xsl:stylesheet>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/fn/key/key097.xml	Mon Sep 03 00:05:16 2018 +0100
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Messages>
+    <Message1>
+        <Response>
+            <CE>
+                <id>1</id>
+                <human>
+                    <name>Frank</name>
+                    <human_information>
+                        <action>New</action>
+                        <title>Doctor</title>
+                    </human_information>
+                    <phone>
+                        <action>Old</action>
+                        <phone_number>1234567</phone_number>
+                    </phone>
+                </human>
+            </CE>
+        </Response>
+        <Response>      
+            <CE>
+                <id>2</id>
+                <human>
+                    <name>Bob</name>
+                    <human_information>
+                        <action>New</action>
+                        <title>Artist</title>
+                    </human_information>
+                    <phone>
+                        <action>Old</action>
+                        <phone_number>13579</phone_number>
+                    </phone>
+                </human>
+            </CE>
+        </Response>
+        <Response>      
+            <CE>
+                <id>3</id>
+                <human>
+                    <name>Alice</name>
+                    <human_information>
+                        <action>Old</action>
+                        <title>Designer</title>
+                    </human_information>
+                    <phone>
+                        <action>New</action>
+                        <phone_number>9876543</phone_number>
+                    </phone>
+                </human>
+            </CE>
+        </Response>            
+    </Message1>
+    <Message2>
+        <Response>      
+            <CE>
+                <id>2</id>
+                <human>
+                    <name>Bob</name>
+                    <human_information>
+                        <title>Artist</title>
+                    </human_information>
+                    <phone>
+                        <phone_number>13579</phone_number>
+                    </phone>
+                    <phone>
+                        <phone_number>24680</phone_number>
+                    </phone>               
+                </human>
+            </CE>
+        </Response>
+        <Response>      
+            <CE>
+                <id>3</id>
+                <human>
+                    <name>Alice</name>
+                    <human_information>
+                        <title>Designer</title>
+                    </human_information>
+                    <phone>
+                        <phone_number>9876543</phone_number>
+                    </phone>
+                    <phone>
+                        <phone_number>0909090</phone_number>
+                    </phone>               
+                </human>
+            </CE>
+        </Response>
+    </Message2>  
+</Messages>
--- a/tests/fn/position/_position-test-set.xml	Fri Jul 20 13:15:12 2018 +0100
+++ b/tests/fn/position/_position-test-set.xml	Mon Sep 03 00:05:16 2018 +0100
@@ -509,6 +509,27 @@
          <assert-xml><![CDATA[<out>X X</out>]]></assert-xml>
       </result>
    </test-case>
+   
+   <test-case name="position-0103">
+      <description>Pass argument depending on position() to user function call: Saxon bug report.</description>
+      <created by="Micahel Kay after Martin Honnen" on="2018-08-24"/>
+      <dependencies>
+         <spec value="XSLT30+"/>
+      </dependencies>
+      <test>
+         <stylesheet file="position-0103.xsl"/>
+         <initial-template name="go"/>
+      </test>
+      <result>
+         <all-of>
+            <assert>/m/out[1][@pos="1"][@value="foo 1, 1"]</assert>
+            <assert>/m/out[2][@pos="1 8"][@value="foo 1, 2"]</assert>
+            <assert>/m/out[3][@pos="1 8 27"][@value="foo 2, 1"]</assert>
+            <assert>/m/out[4][@pos="1 8 27 64"][@value="foo 2, 2"]</assert>
+            <assert>/m/out[5][@pos="1 8 27 64 125"][@value="foo 3, 2"]</assert>
+         </all-of>
+      </result>
+   </test-case>
 
    <test-case name="position-0201">
       <description>Node Set Functions Test of 'position()' function with wildcard.</description>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/fn/position/position-0103.xsl	Mon Sep 03 00:05:16 2018 +0100
@@ -0,0 +1,73 @@
+<?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="select-expression" static="yes" as="xs:string" select="'root/data/foo'"/>
+    
+    <xsl:mode on-no-match="shallow-copy"/>
+    
+    <xsl:output indent="yes"/>
+    
+    <xsl:param name="doc1">
+        <root>
+            <data>
+                <foo>
+                    <value>foo 1, 1</value>
+                </foo>
+                <bar>
+                    <value>bar 1, 1</value>
+                </bar>
+                <foo>
+                    <value>foo 2, 1</value>
+                </foo>
+            </data>
+        </root>
+    </xsl:param>
+    
+    <xsl:param name="doc2">
+        <root>
+            <data>
+                <foo>
+                    <value>foo 1, 2</value>
+                </foo>
+                <bar>
+                    <value>bar 1, 2</value>
+                </bar>
+                <foo>
+                    <value>foo 2, 2</value>
+                </foo>
+                <bar>
+                    <value>bar 2, 2</value>
+                </bar>
+                <foo>
+                    <value>foo 3, 2</value>
+                </foo>
+            </data>
+        </root>
+    </xsl:param>
+    
+    <xsl:template name="go">
+      <m>
+        <xsl:merge>
+            <xsl:merge-source for-each-item="$doc1, $doc2" _select="{$select-expression}">
+                <xsl:merge-key select="value"/>
+            </xsl:merge-source>
+            <xsl:merge-action>
+               <xsl:sequence select="mf:construct-doc((1 to position())!(.*.*.), .)"/>
+            </xsl:merge-action>
+        </xsl:merge>
+      </m>    
+    </xsl:template>
+    
+    <xsl:function name="mf:construct-doc" as="element(out)">
+        <xsl:param name="pos" as="xs:integer*"/>
+        <xsl:param name="first-node" as="node()"/>
+        <out pos="{$pos}" name="{local-name($first-node)}" value="{$first-node/value}"/>
+    </xsl:function>
+    
+
+    
+</xsl:stylesheet>
\ No newline at end of file
--- a/tests/insn/choose/_choose-test-set.xml	Fri Jul 20 13:15:12 2018 +0100
+++ b/tests/insn/choose/_choose-test-set.xml	Mon Sep 03 00:05:16 2018 +0100
@@ -204,6 +204,38 @@
          <assert>/out/*:circle[@r="0" and @cx="10" and @cy="20"]</assert>
       </result>
    </test-case>
+   
+   <test-case name="choose-0106">
+      <description>Same comparison done repeatedly with different namespace contexts</description>
+      <created by="Michael Kay" on="2018-07-31"/>
+      <environment ref="choose-01"/>
+      <dependencies>
+         <spec value="XSLT20+"/>
+      </dependencies>
+      <test>
+         <stylesheet file="choose-0106.xsl"/>
+         <initial-template name="main"/>
+      </test>
+      <result>
+         <assert>/out = 'Three'</assert>
+      </result>
+   </test-case>
+   
+   <test-case name="choose-0107">
+      <description>Same comparison done repeatedly with different default collations</description>
+      <created by="Michael Kay" on="2018-07-31"/>
+      <environment ref="choose-01"/>
+      <dependencies>
+         <spec value="XSLT20+"/>
+      </dependencies>
+      <test>
+         <stylesheet file="choose-0107.xsl"/>
+         <initial-template name="main"/>
+      </test>
+      <result>
+         <assert>/out = 'Two'</assert>
+      </result>
+   </test-case>
 
    <test-case name="choose-0201">
       <description>Wben test occurs with attribute node, with no matches and is missing otherwise clause. No expected output.</description>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/insn/choose/choose-0106.xsl	Mon Sep 03 00:05:16 2018 +0100
@@ -0,0 +1,25 @@
+<xsl:stylesheet 
+    xmlns:xsl    = "http://www.w3.org/1999/XSL/Transform" 
+    xmlns:xs    = "http://www.w3.org/2001/XMLSchema" 
+    xmlns:svg    = "http://www.w3.org/2000/svg" 
+    exclude-result-prefixes="xs" 
+    xmlns:w="http://www.werum.com" 
+    version="2.0">
+    
+    <!-- A nasty little test in which the same comparison is done repeatedly using different namespace
+        contexts -->
+    
+    <xsl:param name="u" select="xs:untypedAtomic('my:problem')"/>
+    <xsl:param name="q" select="QName('http://uri.three/', 'problem')"/>
+    
+    <xsl:template name="main">
+        <out>            
+            <xsl:choose>
+                <xsl:when test="$u = $q" xmlns:my="http://uri.one/">One</xsl:when>
+                <xsl:when test="$u = $q" xmlns:my="http://uri.two/">Two</xsl:when>
+                <xsl:when test="$u = $q" xmlns:my="http://uri.three/">Three</xsl:when>
+                <xsl:otherwise>Fail</xsl:otherwise>               
+            </xsl:choose>
+        </out>
+    </xsl:template>        
+</xsl:stylesheet>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/insn/choose/choose-0107.xsl	Mon Sep 03 00:05:16 2018 +0100
@@ -0,0 +1,23 @@
+<xsl:stylesheet 
+    xmlns:xsl    = "http://www.w3.org/1999/XSL/Transform" 
+    xmlns:xs    = "http://www.w3.org/2001/XMLSchema" 
+    xmlns:svg    = "http://www.w3.org/2000/svg" 
+    exclude-result-prefixes="xs" 
+    xmlns:w="http://www.werum.com" 
+    version="2.0">
+    
+    <!-- A nasty little test in which the same comparison is done repeatedly using different default collations -->
+    
+    <xsl:param name="u" select="'GREEN23'" as="xs:string*"/>
+    <xsl:param name="q" select="'green'" as="xs:string*"/>
+    
+    <xsl:template name="main">
+        <out>            
+            <xsl:choose>
+                <xsl:when test="$u = concat($q, '23')">One</xsl:when>
+                <xsl:when test="$u = concat($q, '23')" default-collation="http://www.w3.org/2013/collation/UCA?strength=secondary">Two</xsl:when>
+                <xsl:otherwise>Fail</xsl:otherwise>               
+            </xsl:choose>
+        </out>
+    </xsl:template>        
+</xsl:stylesheet>
\ No newline at end of file
--- a/tests/insn/merge/_merge-test-set.xml	Fri Jul 20 13:15:12 2018 +0100
+++ b/tests/insn/merge/_merge-test-set.xml	Mon Sep 03 00:05:16 2018 +0100
@@ -1470,5 +1470,75 @@
       </result>
    </test-case>
    
+   <test-case name="merge-096">
+      <description>current-merge-group() called in arguments of function call - Saxon bug 3884</description>
+      <created by="Michael Kay" on="2018-08-24"/>
+      <environment ref="merge002"/>
+      <test>
+         <stylesheet file="merge-096.xsl"/>
+      </test>
+      <result>
+         <all-of>
+            <assert>/root/data/foo[1]/value = "foo 1, 1"</assert>
+            <assert>/root/data/foo[2]/value = "foo 2, 1"</assert>
+            <assert>/root/data/foo[3]/value = "foo 1, 2"</assert>
+            <assert>/root/data/*[6][self::bar]/value = "bar 1, 1"</assert>
+            <assert>/root/data/*[11][self::foo]/value = "foo 3, 2"</assert>
+         </all-of>
+      </result>
+   </test-case>
+   
+   <test-case name="merge-097">
+      <description>Saxon bug 3883. With streamable="no", the output contains 8 item elements.
+         See https://saxonica.plan.io/issues/3883 for reasoning. No snapshot of the nodes is taken.</description>
+      <created by="Michael Kay" on="2018-08-24"/>
+      <test>
+         <stylesheet file="merge-097.xsl"/>
+         <param name="STREAMABLE" static="yes" select="false()"/>
+      </test>
+      <result>
+         <all-of>
+            <assert>count(//item) = 8</assert>
+         </all-of>
+      </result>
+   </test-case>
+   
+   <test-case name="merge-097s">
+      <description>Saxon bug 3883.  With streamable="yes", the output contains 4 item elements.
+         See https://saxonica.plan.io/issues/3883 for reasoning. A snapshot is taken of each node.</description>
+      <created by="Michael Kay" on="2018-08-24"/>
+      <dependencies>
+         <feature value="streaming"/>
+      </dependencies>
+      <test>
+         <stylesheet file="merge-097.xsl"/>
+         <param name="STREAMABLE" static="yes" select="true()"/>
+      </test>
+      <result>
+         <all-of>
+            <assert>count(//item) = 4</assert>
+         </all-of>
+      </result>
+   </test-case>
+   
+   <test-case name="merge-097sf">
+      <description>Saxon bug 3883.  With streamable="yes", the output contains 4 item elements.
+      A snapshot is taken of each node even though we are falling back to use a non-streaming processor.</description>
+      <created by="Michael Kay" on="2018-08-24"/>
+      <dependencies>
+         <feature value="streaming"/>
+         <feature value="streaming-fallback"/>
+      </dependencies>
+      <test>
+         <stylesheet file="merge-097.xsl"/>
+         <param name="STREAMABLE" static="yes" select="true()"/>
+      </test>
+      <result>
+         <all-of>
+            <assert>count(//item) = 4</assert>
+         </all-of>
+      </result>
+   </test-case>
+   
 
 </test-set>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/insn/merge/merge-096.xsl	Mon Sep 03 00:05:16 2018 +0100
@@ -0,0 +1,80 @@
+<?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="select-expression" static="yes" as="xs:string" select="'root/data/foo'"/>
+    
+    <xsl:mode on-no-match="shallow-copy"/>
+    
+    <xsl:output indent="yes"/>
+    
+    <xsl:param name="doc1">
+        <root>
+            <data>
+                <foo>
+                    <value>foo 1, 1</value>
+                </foo>
+                <bar>
+                    <value>bar 1, 1</value>
+                </bar>
+                <foo>
+                    <value>foo 2, 1</value>
+                </foo>
+            </data>
+        </root>
+    </xsl:param>
+    
+    <xsl:param name="doc2">
+        <root>
+            <data>
+                <foo>
+                    <value>foo 1, 2</value>
+                </foo>
+                <bar>
+                    <value>bar 1, 2</value>
+                </bar>
+                <foo>
+                    <value>foo 2, 2</value>
+                </foo>
+                <bar>
+                    <value>bar 2, 2</value>
+                </bar>
+                <foo>
+                    <value>foo 3, 2</value>
+                </foo>
+            </data>
+        </root>
+    </xsl:param>
+    
+    <xsl:template match="/" name="xsl:initial-template">
+        <xsl:merge>
+            <xsl:merge-source for-each-item="$doc1, $doc2" _select="{$select-expression}">
+                <xsl:merge-key select="true()"/>
+            </xsl:merge-source>
+            <xsl:merge-action>
+                <xsl:sequence select="mf:construct-doc((1 to position())!(.*.*.), tail(current-merge-group()), .)"/>
+            </xsl:merge-action>
+        </xsl:merge>
+    </xsl:template>
+    
+    <xsl:function name="mf:construct-doc" as="document-node()">
+        <xsl:param name="pos" as="xs:integer*"/>
+        <xsl:param name="nodes" as="node()*"/>
+        <xsl:param name="first-node" 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="{$select-expression}" mode="construct">
+        <xsl:param name="nodes"/>
+        <xsl:apply-templates select="."/>
+        <xsl:apply-templates select="$nodes"/>
+    </xsl:template>    
+    
+</xsl:stylesheet>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/insn/merge/merge-097-A.xml	Mon Sep 03 00:05:16 2018 +0100
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/insn/merge/merge-097-B.xml	Mon Sep 03 00:05:16 2018 +0100
@@ -0,0 +1,12 @@
+<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>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/insn/merge/merge-097.xsl	Mon Sep 03 00:05:16 2018 +0100
@@ -0,0 +1,61 @@
+<?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="STREAMABLE" static="true" select="true()"/>
+    
+    <xsl:param name="input-uri" as="xs:string" select="'.'"/>
+    
+    <xsl:param name="file-pattern" as="xs:string" select="'merge-097-*.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">
+      <out>
+        <xsl:merge>
+            <xsl:merge-source
+                for-each-source="sort(uri-collection($input-uri || '?select=' || $file-pattern))"
+                _select="{$merge-select-expression}"
+                _streamable="{$STREAMABLE}">
+                <xsl:merge-key select="true()"/>
+            </xsl:merge-source>
+            <xsl:merge-action>
+                <xsl:message>Doing merge action</xsl:message>
+                <xsl:sequence select="let $group-tail := tail(current-merge-group()) return mf:construct-doc(., $group-tail)"/>
+            </xsl:merge-action>
+        </xsl:merge>
+      </out>        
+    </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"/>
+        <one><xsl:apply-templates select="."/></one>
+        <two><xsl:apply-templates select="$nodes"/></two>
+    </xsl:template>
+    
+</xsl:stylesheet>
\ No newline at end of file
--- a/tests/insn/message/_message-test-set.xml	Fri Jul 20 13:15:12 2018 +0100
+++ b/tests/insn/message/_message-test-set.xml	Mon Sep 03 00:05:16 2018 +0100
@@ -29,9 +29,10 @@
    <test-case name="message-0001">
       <description>
          Output a message that cannot be serialized - specifically, a free-standing attribute node. 
-         Under erratum E20, this is a recoverable error - the processor may fail or may report an error. 
+         Under erratum E20 for XSLT 2.0, this is a recoverable error - the processor may fail or may report an error. 
          This test shows both paths.</description>
       <created by="Michael Kay" on="2012-11-07"/>
+      <modified by="Michael Kay" on="2018-09-02" change="See bug 30283. Stylesheet changed and test split into 2.0/3.0 versions"/>
       <dependencies>
          <spec value="XSLT20+"/>
       </dependencies>
@@ -46,6 +47,24 @@
          </any-of>
       </result>
    </test-case>
+   
+   <test-case name="message-0001a">
+      <description>
+         Output a message that cannot be serialized - specifically, a free-standing attribute node. 
+         XSLT 3.0 says that the transformation does not fail (though the output is left unspecified)</description>
+      <created by="Michael Kay" on="2012-11-07"/>
+      <modified by="Michael Kay" on="2018-09-02" change="See bug 30283. Stylesheet changed and test split into 2.0/3.0 versions"/>
+      <dependencies>
+         <spec value="XSLT30+"/>
+      </dependencies>
+      <test>
+         <stylesheet file="message-0001.xsl"/>
+         <initial-template name="main"/>
+      </test>
+      <result>
+            <assert-xml><![CDATA[<out/>]]></assert-xml>
+      </result>
+   </test-case>
 
    <test-case name="message-0002">
       <description>Check that default error code is XTMM9000</description>
@@ -708,19 +727,16 @@
    <test-case name="message-0404">
       <description>Tests dynamic error evaluating content of xsl:message instruction.</description>
       <created by="Michael Kay" on="2018-03-28"/>
+      <modified by="Michael Kay" on="2018-09-02" change="Bug 30283. Make this an XSLT 3.0 test. The XSLT 3.0 spec is clear that the transformation must not fail."/>
       <environment ref="message-04"/>
       <dependencies>
-         <spec value="XSLT20+"/>
+         <spec value="XSLT30+"/>
       </dependencies>
       <test>
          <stylesheet file="message-0404.xsl"/>
       </test>
       <result>
-         <any-of>
-            <!-- Outcome is not well-defined by the spec, but I think with terminate=no, the error can be ignored -->
-            <assert>/out</assert>
-            <error code="FOAR0001"/>
-         </any-of>
+         <assert>/out</assert>
       </result>
    </test-case>
    
@@ -757,4 +773,50 @@
          <error code="XTMM9000"/>
       </result>
    </test-case>
+   
+   <test-case name="message-0407">
+      <description>xsl:message outputs an array</description>
+      <created by="Michael Kay" on="2018-09-02"/>
+      <environment ref="message-04"/>
+      <dependencies>
+         <spec value="XSLT30+"/>
+         <feature value="XPath_3.1"/>
+      </dependencies>
+      <test>
+         <stylesheet file="message-0407.xsl"/>
+      </test>
+      <result>
+         <assert>/out</assert>
+      </result>
+   </test-case>
+   
+   <test-case name="message-0408">
+      <description>xsl:message outputs a map. The transformation succeeds, but the message content is undefined.</description>
+      <created by="Michael Kay" on="2018-09-02"/>
+      <environment ref="message-04"/>
+      <dependencies>
+         <spec value="XSLT30+"/>
+      </dependencies>
+      <test>
+         <stylesheet file="message-0408.xsl"/>
+      </test>
+      <result>
+         <assert>/out</assert>
+      </result>
+   </test-case>
+   
+   <test-case name="message-0409">
+      <description>xsl:message outputs a function item. The transformation succeeds, but the message content is undefined.</description>
+      <created by="Michael Kay" on="2018-09-02"/>
+      <environment ref="message-04"/>
+      <dependencies>
+         <spec value="XSLT30+"/>
+      </dependencies>
+      <test>
+         <stylesheet file="message-0409.xsl"/>
+      </test>
+      <result>
+         <assert>/out</assert>
+      </result>
+   </test-case>
 </test-set>
--- a/tests/insn/message/message-0001.xsl	Fri Jul 20 13:15:12 2018 +0100
+++ b/tests/insn/message/message-0001.xsl	Mon Sep 03 00:05:16 2018 +0100
@@ -3,10 +3,11 @@
 <!-- Purpose: Test output of a message that cannot be serialized.
        According to XSLT 2.0 second edition (following erratum E20) this
        is a recoverable error, so this test case may either generate an error
-       or output the element <out/>  -->
+       or output the element <out/>. XSLT 3.0 says that the transformation does not fail,
+       though the output is left unspecified -->
 
    <t:variable name="v">
-        <a xmlns:xsl="http://www.w3.org/1999/XSL/Transform">boo</a>
+        <a xmlns:xsl="http://www.w3.org/1999/XSL/Transform" att="An attribute">boo</a>
     </t:variable>
 
    <t:template name="main">
--- a/tests/insn/message/message-0406.xsl	Fri Jul 20 13:15:12 2018 +0100
+++ b/tests/insn/message/message-0406.xsl	Mon Sep 03 00:05:16 2018 +0100
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <t:transform xmlns:t="http://www.w3.org/1999/XSL/Transform" version="3.0">
-   <!-- Purpose: Tests the error code of an xsl:message instruction not being a valid QName. -->
+   <!-- Purpose: x. -->
 
    <t:param name="zero" select="0"/>
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/insn/message/message-0407.xsl	Mon Sep 03 00:05:16 2018 +0100
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<t:transform xmlns:t="http://www.w3.org/1999/XSL/Transform" version="3.0">
+   <!-- Purpose: xsl:message outputs an array -->
+   <t:template match="/">
+      <out>
+         <t:message select="['a', 'b', 'c']"/>
+      </out>
+   </t:template>
+</t:transform>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/insn/message/message-0408.xsl	Mon Sep 03 00:05:16 2018 +0100
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<t:transform xmlns:t="http://www.w3.org/1999/XSL/Transform" version="3.0">
+   <!-- Purpose: xsl:message outputs a map -->
+   <t:template match="/">
+      <out>
+         <t:message select="map{1: true(), 0: false()}"/>
+      </out>
+   </t:template>
+</t:transform>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/insn/message/message-0409.xsl	Mon Sep 03 00:05:16 2018 +0100
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<t:transform xmlns:t="http://www.w3.org/1999/XSL/Transform" version="3.0">
+   <!-- Purpose: xsl:message outputs a function item -->
+   <t:template match="/">
+      <out>
+         <t:message select="function($x){$x*2}"/>
+      </out>
+   </t:template>
+</t:transform>
--- a/tests/insn/try/_try-test-set.xml	Fri Jul 20 13:15:12 2018 +0100
+++ b/tests/insn/try/_try-test-set.xml	Mon Sep 03 00:05:16 2018 +0100
@@ -588,4 +588,36 @@
          <assert>/out='test: Bang!'</assert>
       </result>
    </test-case>
+   
+   <test-case name="try-033">
+      <description>rollback-output="no": recovery still possible because no output written</description>
+      <keywords>xsl:try</keywords>
+      <created by="Michael Kay" on="2018-07-26"/>
+      <dependencies>
+         <spec value="XSLT30+"/>
+      </dependencies>
+      <test>
+         <stylesheet file="try-033.xsl"/>
+         <initial-template name="main"/>
+      </test>
+      <result>
+         <assert>/out='Error err:FODC0002 was caught!'</assert>
+      </result>
+   </test-case>
+   
+   <test-case name="try-034">
+      <description>rollback-output="no": recovery not possible because lots of output written</description>
+      <keywords>xsl:try</keywords>
+      <created by="Michael Kay" on="2018-07-26"/>
+      <dependencies>
+         <spec value="XSLT30+"/>
+      </dependencies>
+      <test>
+         <stylesheet file="try-034.xsl"/>
+         <initial-template name="main"/>
+      </test>
+      <result>
+         <error code="XTDE3530"/>
+      </result>
+   </test-case>
 </test-set>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/insn/try/try-033.xsl	Mon Sep 03 00:05:16 2018 +0100
@@ -0,0 +1,22 @@
+<?xml version="1.0"?> 
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"
+  xmlns:err="http://www.w3.org/2005/xqt-errors" exclude-result-prefixes="err"
+  expand-text="true">
+
+  <!-- xsl:try with rollback=no: a case where catching the error probably works because no output has been written -->
+
+  <xsl:template name="main">
+    <out>
+      <xsl:try rollback-output="no">
+        <xsl:source-document href="rubbish.xml">
+          <xsl:value-of select="count(//*)"/>
+        </xsl:source-document>
+        <xsl:catch errors="*">
+          <xsl:text>Error {$err:code} was caught!</xsl:text>
+        </xsl:catch>
+      </xsl:try>
+    </out>
+  </xsl:template>
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/insn/try/try-034.xsl	Mon Sep 03 00:05:16 2018 +0100
@@ -0,0 +1,24 @@
+<?xml version="1.0"?> 
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"
+  xmlns:err="http://www.w3.org/2005/xqt-errors" exclude-result-prefixes="err">
+
+  <!-- xsl:try with rollback=no: a case where catching the error probably fails because lots of output has been written -->
+
+  <xsl:template name="main">
+    <out>
+      <xsl:try rollback-output="no">
+        <xsl:for-each select="1 to 1000">
+          <in/>
+        </xsl:for-each>
+        <xsl:source-document href="rubbish.xml">
+          <xsl:value-of select="count(//*)"/>
+        </xsl:source-document>
+        <xsl:catch errors="*">
+          <xsl:text>Error {$err:code} was caught!</xsl:text>
+        </xsl:catch>
+      </xsl:try>
+    </out>
+  </xsl:template>
+
+</xsl:stylesheet>
--- a/tests/strm/si-fork/_si-fork-test-set.xml	Fri Jul 20 13:15:12 2018 +0100
+++ b/tests/strm/si-fork/_si-fork-test-set.xml	Mon Sep 03 00:05:16 2018 +0100
@@ -831,6 +831,28 @@
       </result>
    </test-case>
    
+   <test-case name="si-fork-816">
+      <description>Streaming with xsl:fork and map expressions. See Saxon bug 3888.</description>
+      <created by="Michael Kay after Martin Honnen" on="2018-08-29"/>
+      <environment>
+         <source file="si-fork-816.xml" role="." streaming="true"/>
+      </environment>
+      <dependencies>
+         <spec value="XSLT30+"/>
+         <feature value="streaming"/>
+         <feature value="serialization"/>
+      </dependencies>
+      <test>
+         <stylesheet file="si-fork-816.xsl"/>
+      </test>
+      <result>
+         <all-of>
+            <assert>deep-equal(/CustInvoiceJour/CustInvoiceTrans/LineAmount/number(), (125, 215, 40))</assert>
+            <assert>deep-equal(/CustInvoiceJour/TaxTrans/TaxValue/number(), (21, 21, 15))</assert>
+         </all-of>
+      </result>
+   </test-case>
+   
    <test-case name="si-fork-901">
       <description>Non-streamable xsl:fork - returns streamed nodes</description>
       <keywords>multiple-xsl-sequence-children AxisStep striding XTSE3430 illegally-returning-streamed-nodes</keywords>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/strm/si-fork/si-fork-816.xml	Mon Sep 03 00:05:16 2018 +0100
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CustInvoiceJour class="entity">
+    <CustInvoiceTrans class="entity">
+        <InventTransId>AABB</InventTransId>
+        <InvoiceId>SI100</InvoiceId>
+        <ItemId>444</ItemId>
+        <LineAmount>100</LineAmount>
+    </CustInvoiceTrans>
+    <CustInvoiceTrans class="entity">
+        <InventTransId>BBCC</InventTransId>
+        <InvoiceId>SI100</InvoiceId>
+        <ItemId>444</ItemId>
+        <LineAmount>25</LineAmount>
+    </CustInvoiceTrans>
+    <CustInvoiceTrans class="entity">
+        <InventTransId>CCDD</InventTransId>
+        <InvoiceId>SI100</InvoiceId>
+        <ItemId>555</ItemId>
+        <LineAmount>200</LineAmount>
+    </CustInvoiceTrans>
+    <CustInvoiceTrans class="entity">
+        <InventTransId>DDEE</InventTransId>
+        <InvoiceId>SI100</InvoiceId>
+        <ItemId>555</ItemId>
+        <LineAmount>15</LineAmount>
+    </CustInvoiceTrans>         
+    <CustInvoiceTrans class="entity">
+        <InventTransId>EEFF</InventTransId>
+        <InvoiceId>SI100</InvoiceId>
+        <ItemId>12345</ItemId>
+        <LineAmount>40</LineAmount>
+    </CustInvoiceTrans>
+    <TaxTrans class="entity">
+        <InventTransId>AABB</InventTransId>
+        <TaxAmount>-21</TaxAmount>
+        <TaxBaseAmount>-100</TaxBaseAmount>
+        <TaxValue>21.00</TaxValue>
+    </TaxTrans>
+    <TaxTrans class="entity">
+        <InventTransId>BBCC</InventTransId>
+        <TaxAmount>-5.25</TaxAmount>
+        <TaxBaseAmount>-25</TaxBaseAmount>
+        <TaxValue>21.00</TaxValue>
+    </TaxTrans>
+    <TaxTrans class="entity">
+        <InventTransId>CCDD</InventTransId>
+        <TaxAmount>-42</TaxAmount>
+        <TaxBaseAmount>-200</TaxBaseAmount>
+        <TaxValue>21.00</TaxValue>
+    </TaxTrans>
+    <TaxTrans class="entity">
+        <InventTransId>DDEE</InventTransId>
+        <TaxAmount>-3.15</TaxAmount>
+        <TaxBaseAmount>-15</TaxBaseAmount>
+        <TaxValue>15</TaxValue>
+    </TaxTrans>
+    <TaxTrans class="entity">
+        <InventTransId>EEFF</InventTransId>
+        <TaxAmount>-8.40</TaxAmount>
+        <TaxBaseAmount>-40</TaxBaseAmount>
+        <TaxValue>15</TaxValue>
+    </TaxTrans>         
+</CustInvoiceJour>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/strm/si-fork/si-fork-816.xsl	Mon Sep 03 00:05:16 2018 +0100
@@ -0,0 +1,65 @@
+<?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:map="http://www.w3.org/2005/xpath-functions/map"
+  exclude-result-prefixes="#all"
+  expand-text="yes"
+  version="3.0">
+  
+  <xsl:mode streamable="yes" on-no-match="shallow-copy" use-accumulators="#all"/>
+  
+  <xsl:strip-space elements="*"/>
+  <xsl:output indent="yes"/>
+  
+  <xsl:accumulator name="inventtransid" as="xs:string?" initial-value="()" streamable="yes">
+    <xsl:accumulator-rule match="CustInvoiceTrans" select="()"/>
+    <xsl:accumulator-rule match="CustInvoiceTrans/InventTransId/text()" select="string()"/>
+  </xsl:accumulator>
+  
+  <xsl:accumulator name="map-inventtrans-to-itemid" as="map(xs:string, xs:integer)" initial-value="map{}" streamable="yes">
+    <xsl:accumulator-rule match="CustInvoiceTrans/ItemId/text()" select="map:put($value, accumulator-before('inventtransid'), xs:integer(.))"/>
+  </xsl:accumulator>
+  
+  <xsl:template match="/*">
+    <xsl:copy>
+      <xsl:fork>
+        <xsl:sequence>
+          <xsl:for-each-group select="CustInvoiceTrans!copy-of()" group-by="ItemId">
+            <xsl:copy>
+              <xsl:apply-templates select="@*"/>
+              <xsl:apply-templates>
+                <xsl:with-param name="sum" tunnel="yes" select="sum(current-group()/LineAmount)"/>
+              </xsl:apply-templates>
+            </xsl:copy>
+          </xsl:for-each-group>
+        </xsl:sequence>
+        <xsl:sequence>
+          <xsl:for-each-group select="TaxTrans!copy-of()" group-by="accumulator-before('map-inventtrans-to-itemid')(InventTransId)">
+            <xsl:copy>
+              <xsl:apply-templates select="@*"/>
+              <xsl:apply-templates>
+                <xsl:with-param name="sums" tunnel="yes" select="map { 'TaxAmount' : sum(current-group()/TaxAmount), 'TaxBaseAmount' : sum(current-group()/TaxBaseAmount) }"/>
+              </xsl:apply-templates>
+            </xsl:copy>
+          </xsl:for-each-group>
+        </xsl:sequence>
+      </xsl:fork>
+    </xsl:copy>
+  </xsl:template>
+  
+  <xsl:template match="CustInvoiceTrans/LineAmount">
+    <xsl:param name="sum" tunnel="yes"/>
+    <xsl:copy>{$sum}</xsl:copy>
+  </xsl:template>
+  
+  <xsl:template match="TaxTrans/TaxAmount">
+    <xsl:param name="sums" tunnel="yes"/>
+    <xsl:copy>{$sums?TaxAmount}</xsl:copy>
+  </xsl:template>
+  
+  <xsl:template match="TaxTrans/TaxBaseAmount">
+    <xsl:param name="sums" tunnel="yes"/>
+    <xsl:copy>{$sums?TaxBaseAmount}</xsl:copy>
+  </xsl:template>
+  
+</xsl:stylesheet>
\ No newline at end of file
--- a/tests/type/namespace/_namespace-test-set.xml	Fri Jul 20 13:15:12 2018 +0100
+++ b/tests/type/namespace/_namespace-test-set.xml	Mon Sep 03 00:05:16 2018 +0100
@@ -46,6 +46,11 @@
          <content><![CDATA[<doc><a:a xmlns:a="http://a.uri/"> </a:a><b:a xmlns:b="http://b.uri/"> </b:a><A:b xmlns:A="http://a.uri/"> </A:b><B:b xmlns:B="http://b.uri/"> </B:b></doc>]]></content>
       </source>
    </environment>
+   
+   <environment name="namespace-19">
+      <source role="." file="namespace-19a.xml"/>
+      <source file="namespace-19b.xml"/>
+   </environment>
 
    <environment name="namespace-23">
       <source role=".">
@@ -978,6 +983,24 @@
          </all-of>
       </result>
    </test-case>
+   
+   <test-case name="namespace-1901">
+      <description>Test that a no-namespace element copied into a document having a default namespace
+         acquires an xmlns="" undeclaration. Saxon bug 3889.</description>
+      <created by="Michael Kay" on="2018-08-31"/>
+      <environment ref="namespace-19"/>
+      <dependencies>
+         <spec value="XSLT20+"/>
+         <feature value="serialization"/>
+      </dependencies>
+      <test>
+         <stylesheet file="namespace-1901.xsl"/>
+         <output serialize="yes"/>
+      </test>
+      <result>
+         <serialization-matches><![CDATA[<header xmlns=['"]['"]><x>]]></serialization-matches>
+      </result>
+   </test-case>
 
    <test-case name="namespace-2001">
       <description>TEST copied namespace clashing with namespace of parent element Results require
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/type/namespace/namespace-1901.xsl	Mon Sep 03 00:05:16 2018 +0100
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+    xmlns:b="test.com/b"
+    xmlns:c="test.com/c" 
+    exclude-result-prefixes="#all" version="3.0">
+    
+    <xsl:output method="xml" indent="no"/>
+
+    <!-- Test that the no-namespace "header" element is serialized correctly
+         with an xmlns="" undeclaration. Saxon bug 3889 -->
+ 
+    <xsl:template match="/*">
+        <xsl:copy>
+            <xsl:sequence select="doc('namespace-19b.xml')/b:request"/>
+        </xsl:copy>
+    </xsl:template>
+    
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/type/namespace/namespace-19a.xml	Mon Sep 03 00:05:16 2018 +0100
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="test.com/c">
+    <data>DATA</data>
+</form>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/type/namespace/namespace-19b.xml	Mon Sep 03 00:05:16 2018 +0100
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<b:request xmlns:b="test.com/b">
+    <header><x>HEADER</x></header>
+    <b:service>SERVICE</b:service>
+</b:request>