You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by mu...@apache.org on 2023/10/08 15:20:16 UTC

[xalan-java] branch xalan-j_xslt3.0 updated: doing minor bug fixes within xsl:function and xsl:for-each instructions implementations. also adding few new related working test cases. the xalanj test cases within this dev repos branch, have been refactored to better organize the xalanj test suite codebase.

This is an automated email from the ASF dual-hosted git repository.

mukulg pushed a commit to branch xalan-j_xslt3.0
in repository https://gitbox.apache.org/repos/asf/xalan-java.git


The following commit(s) were added to refs/heads/xalan-j_xslt3.0 by this push:
     new 60a039cc doing minor bug fixes within xsl:function and xsl:for-each instructions implementations. also adding few new related working test cases. the xalanj test cases within this dev repos branch, have been refactored to better organize the xalanj test suite codebase.
     new faf7a848 Merge pull request #98 from mukulga/xalan-j_xslt3.0_mukul
60a039cc is described below

commit 60a039cce41f85d8207c675ac2d415d036a91ced
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Sun Oct 8 20:46:03 2023 +0530

    doing minor bug fixes within xsl:function and xsl:for-each instructions implementations. also adding few new related working test cases. the xalanj test cases within this dev repos branch, have been refactored to better organize the xalanj test suite codebase.
---
 src/org/apache/xalan/templates/ElemForEach.java    |  30 +----
 src/org/apache/xalan/templates/ElemFunction.java   |  10 +-
 tests/grouping/gold/test26.out                     |   4 +-
 tests/grouping/test26.xsl                          |   4 +-
 tests/org/apache/xalan/xslt3/AllXsl3Tests.java     |  83 ++------------
 .../apache/xalan/xslt3/RecursiveFunctionTests.java | 121 +++++++++++++++++++++
 tests/org/apache/xalan/xslt3/Xsl3TestSuite1.java   |  36 ++++++
 .../{AllXsl3Tests.java => Xsl3TestSuite2.java}     |  12 +-
 tests/xsl_recursion/gold/test1.out                 |   4 +
 tests/xsl_recursion/gold/test2.out                 |  21 ++++
 tests/xsl_recursion/gold/test3.out                 |   4 +
 tests/xsl_recursion/gold/test4.out                 |  21 ++++
 tests/xsl_recursion/gold/test5.out                 |   4 +
 tests/xsl_recursion/gold/test6.out                 |  21 ++++
 tests/xsl_recursion/gold/test7.out                 |  21 ++++
 .../test26.xsl => xsl_recursion/test1.xsl}         |  34 +++---
 tests/xsl_recursion/test1_a.xml                    |   5 +
 tests/xsl_recursion/test2.xsl                      |  72 ++++++++++++
 .../test26.xsl => xsl_recursion/test3.xsl}         |  39 ++++---
 tests/xsl_recursion/test4.xsl                      |  77 +++++++++++++
 .../test26.xsl => xsl_recursion/test5.xsl}         |  36 +++---
 tests/xsl_recursion/test6.xsl                      |  74 +++++++++++++
 tests/xsl_recursion/test7.xsl                      |  79 ++++++++++++++
 23 files changed, 653 insertions(+), 159 deletions(-)

diff --git a/src/org/apache/xalan/templates/ElemForEach.java b/src/org/apache/xalan/templates/ElemForEach.java
index 03378d16..47c7cb51 100644
--- a/src/org/apache/xalan/templates/ElemForEach.java
+++ b/src/org/apache/xalan/templates/ElemForEach.java
@@ -49,20 +49,12 @@ import org.apache.xpath.operations.Operation;
 import org.apache.xpath.operations.Variable;
 
 /**
- * XSLT 3.0 for-each element.
- * 
- * <xsl:for-each 
- *           select = expression>
- *     <!-- Content: (xsl:sort*, sequence-constructor) -->
- * </xsl:for-each>
+ * Implementation of the XSLT 3.0 xsl:for-each instruction.
  * 
  * Ref : https://www.w3.org/TR/xslt-30/#for-each
  * 
  * @xsl.usage advanced
  */
-/*
- * Implementation of the XSLT 3.0 xsl:for-each instruction.
- */
 public class ElemForEach extends ElemTemplateElement implements ExpressionOwner
 {
     static final long serialVersionUID = 6018140636363583690L;
@@ -319,8 +311,6 @@ public class ElemForEach extends ElemTemplateElement implements ExpressionOwner
    */
   public void transformSelectedNodes(TransformerImpl transformer) throws 
                                                              TransformerException {
-
-    final XPathContext xctxtOriginal = transformer.getXPathContext();
     
     XPathContext xctxt = transformer.getXPathContext();
     
@@ -333,9 +323,7 @@ public class ElemForEach extends ElemTemplateElement implements ExpressionOwner
             XNodeSet nodeSet = XslTransformEvaluationHelper.getXNodeSetFromResultSequence((ResultSequence)evalResult, 
                                                                                                                   (DTMManager)xctxt);             
             if (nodeSet == null) {
-               processResultSequence(transformer, xctxt, evalResult);
-               transformer.setXPathContext(xctxtOriginal);
-               
+               processResultSequence(transformer, xctxt, evalResult);               
                return;
             }
             else {
@@ -351,8 +339,6 @@ public class ElemForEach extends ElemTemplateElement implements ExpressionOwner
                                                                                                                   (DTMManager)xctxt);             
             if (nodeSet == null) {
                 processResultSequence(transformer, xctxt, evalResult);
-                transformer.setXPathContext(xctxtOriginal);
-
                 return;
             }
             else {
@@ -368,8 +354,6 @@ public class ElemForEach extends ElemTemplateElement implements ExpressionOwner
                                                                                                                   (DTMManager)xctxt);             
             if (nodeSet == null) {
                 processResultSequence(transformer, xctxt, evalResult);
-                transformer.setXPathContext(xctxtOriginal);
-
                 return;
             }
             else {
@@ -385,8 +369,6 @@ public class ElemForEach extends ElemTemplateElement implements ExpressionOwner
                                                                                                               (DTMManager)xctxt);             
         if (nodeSet == null) {
             processResultSequence(transformer, xctxt, evalResult);
-            transformer.setXPathContext(xctxtOriginal);
-
             return;
         }
         else {
@@ -402,8 +384,6 @@ public class ElemForEach extends ElemTemplateElement implements ExpressionOwner
                                                                                                               (DTMManager)xctxt);             
         if (nodeSet == null) {
             processResultSequence(transformer, xctxt, evalResult);
-            transformer.setXPathContext(xctxtOriginal);
-
             return;
         }
         else {
@@ -419,8 +399,6 @@ public class ElemForEach extends ElemTemplateElement implements ExpressionOwner
                                                                                                                   (DTMManager)xctxt);             
             if (nodeSet == null) {
                 processResultSequence(transformer, xctxt, evalResult);
-                transformer.setXPathContext(xctxtOriginal);
-
                 return;
             }
             else {
@@ -556,10 +534,6 @@ public class ElemForEach extends ElemTemplateElement implements ExpressionOwner
       sourceNodes.detach();
     }
     
-    // restore the xpath context, to where it was before this 
-    // xsl:for-each instruction began an evaluation.
-    transformer.setXPathContext(xctxtOriginal);
-    
   }
 
   /**
diff --git a/src/org/apache/xalan/templates/ElemFunction.java b/src/org/apache/xalan/templates/ElemFunction.java
index cc3e4078..5881a4dd 100644
--- a/src/org/apache/xalan/templates/ElemFunction.java
+++ b/src/org/apache/xalan/templates/ElemFunction.java
@@ -198,14 +198,16 @@ public class ElemFunction extends ElemTemplate
          }
       }
       
-      // end, Validate few of the information of xsl:function's xsl:param declarations                        
+      // end, Validate few of the information of xsl:function's xsl:param declarations            
+      
+      VariableStack varStack = xctxt.getVarStack();
       
       if (xslParamMap.size() > 0) {
           // Set all xsl:function parameters to xpath context's variable stack,
           // so that XSL instructions after xsl:param declarations can dereference
-          // those parameters.
+          // those parameters.                    
           
-          VariableStack varStack = xctxt.getVarStack();
+          varStack.unlink();
           int argsFrame = varStack.link(xslParamMap.size());            
                     
           int paramIdx = 0;
@@ -245,7 +247,7 @@ public class ElemFunction extends ElemTemplate
               else {
                  break; 
               }
-          }     
+          }                    
       }            
       
       int nodeDtmHandle = transformer.transformToGlobalRTF(this);
diff --git a/tests/grouping/gold/test26.out b/tests/grouping/gold/test26.out
index 7d692c0b..c1967960 100644
--- a/tests/grouping/gold/test26.out
+++ b/tests/grouping/gold/test26.out
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?><result>
+<?xml version="1.0" encoding="UTF-8"?><RESULT>
   <PARTS expired="false">
     <part>
     <id>1</id>
@@ -28,4 +28,4 @@
     <expiryDate>2006-10-05</expiryDate>
   </part>
   </PARTS>
-</result>
+</RESULT>
diff --git a/tests/grouping/test26.xsl b/tests/grouping/test26.xsl
index 7d6623c9..cb12090c 100644
--- a/tests/grouping/test26.xsl
+++ b/tests/grouping/test26.xsl
@@ -17,13 +17,13 @@
   <xsl:output method="xml" indent="yes"/>
   
   <xsl:template match="/parts">     
-     <result>
+     <RESULT>
        <xsl:for-each-group select="part" group-by="xs:date(expiryDate) lt current-date()">
           <PARTS expired="{current-grouping-key()}">           
              <xsl:copy-of select="current-group()"/>
           </PARTS>
        </xsl:for-each-group>
-     </result>
+     </RESULT>
   </xsl:template>
   
   <!--
diff --git a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
index aede2310..cfdae7c6 100644
--- a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
+++ b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
@@ -16,89 +16,28 @@
  */
 package org.apache.xalan.xslt3;
 
-import org.apache.xalan.xpath3.BuiltinFunctionsNamespceTests;
-import org.apache.xalan.xpath3.DynamicFunctionCallTests;
-import org.apache.xalan.xpath3.FnAbsTests;
-import org.apache.xalan.xpath3.FnAvgTests;
-import org.apache.xalan.xpath3.FnCodepointEqualTests;
-import org.apache.xalan.xpath3.FnCodepointsToStringTests;
-import org.apache.xalan.xpath3.FnCompareTests;
-import org.apache.xalan.xpath3.FnContainsTokenTests;
-import org.apache.xalan.xpath3.FnDataTests;
-import org.apache.xalan.xpath3.FnDistinctValuesTests;
-import org.apache.xalan.xpath3.FnDocTests;
-import org.apache.xalan.xpath3.FnFilterTests;
-import org.apache.xalan.xpath3.FnFoldLeftTests;
-import org.apache.xalan.xpath3.FnFoldRightTests;
-import org.apache.xalan.xpath3.FnForEachPairTests;
-import org.apache.xalan.xpath3.FnForEachTests;
-import org.apache.xalan.xpath3.FnIndexOfTests;
-import org.apache.xalan.xpath3.FnMaxTests;
-import org.apache.xalan.xpath3.FnMinTests;
-import org.apache.xalan.xpath3.FnParseXmlFragmentTests;
-import org.apache.xalan.xpath3.FnParseXmlTests;
-import org.apache.xalan.xpath3.FnRoundTests;
-import org.apache.xalan.xpath3.FnSortTests;
-import org.apache.xalan.xpath3.FnStringJoinTests;
-import org.apache.xalan.xpath3.FnStringToCodepointsTests;
-import org.apache.xalan.xpath3.FnTokenizeTests;
-import org.apache.xalan.xpath3.FnUnparsedTextTests;
-import org.apache.xalan.xpath3.ForExprTests;
-import org.apache.xalan.xpath3.IfExprTests;
-import org.apache.xalan.xpath3.InlineFunctionItemExprTests;
-import org.apache.xalan.xpath3.InstanceOfExprTests;
-import org.apache.xalan.xpath3.LetExprTests;
-import org.apache.xalan.xpath3.NodeComparisonTests;
-import org.apache.xalan.xpath3.QuantifiedExprTests;
-import org.apache.xalan.xpath3.RangeExprTests;
-import org.apache.xalan.xpath3.SequenceConstructorTests;
-import org.apache.xalan.xpath3.SequenceFunctionTests;
-import org.apache.xalan.xpath3.SequenceTests;
-import org.apache.xalan.xpath3.SimpleMapOperatorTests;
-import org.apache.xalan.xpath3.StringConcatExprTests;
-import org.apache.xalan.xpath3.StringTests;
-import org.apache.xalan.xpath3.TrignometricAndExponentialFunctionTests;
-import org.apache.xalan.xpath3.ValueComparisonTests;
-import org.apache.xalan.xpath3.XPathArithmeticOnDurationValuesTests;
-import org.apache.xalan.xpath3.XsConstructorFunctionTests;
-import org.apache.xalan.xpath3.XsDurationComponentExtractionFunctionTests;
 import org.junit.runner.RunWith;
 import org.junit.runners.Suite;
 import org.junit.runners.Suite.SuiteClasses;
 
 /**
- * A JUnit 4 test suite, for XSLT 3.0 and XPath 3.1 tests.
+ * A top level JUnit 4 test suite, for XalanJ XSLT 3.0 and XPath 3.1 
+ * tests. This JUnit tests class is an entry point, to invoke all of
+ * the XalanJ XSLT 3.0 and XPath 3.1 tests supported by this class.
+ * 
+ * All the XSLT and XPath tests, supported by this class are further
+ * divided between two JUnit sub test suites.
+ * 
+ * For all the XSLT and XPath tests supported by this test suite, 
+ * the XSLT transformation expected output files (i.e, the gold files) are 
+ * sensitive to the whitespace contents available within those files.
  * 
  * @author Mukul Gandhi <mu...@apache.org>
  * 
  * @xsl.usage advanced
  */
-/*
- *  For all the XSLT and XPath tests supported by this test suite, 
- *  the XSLT transformation expected output files (i.e, the gold files) are 
- *  sensitive to the whitespace contents available within those files.
- */
 @RunWith(Suite.class)
-@SuiteClasses({ AnalyzeStringTests.class, AttributeTests.class, GroupingTests.class,
-                GroupingWithSortTests.class, RtfMigrationTests.class, QuantifiedExprTests.class, 
-                FnUnparsedTextTests.class, FnTokenizeTests.class, FnStringJoinTests.class,
-                FnAbsTests.class, StringTests.class, XsConstructorFunctionTests.class, 
-                FnIndexOfTests.class, SequenceTests.class, RangeExprTests.class, 
-                W3c_xslt30_IterateTests.class, W3c_xslt30_AxesTests.class, XslIterateTests.class,
-                ValueComparisonTests.class, InlineFunctionItemExprTests.class, FnForEachTests.class, 
-                FnFilterTests.class, DynamicFunctionCallTests.class, IfExprTests.class, 
-                ForExprTests.class, LetExprTests.class, FnDistinctValuesTests.class,
-                TrignometricAndExponentialFunctionTests.class, BuiltinFunctionsNamespceTests.class,
-                SequenceConstructorTests.class, StringConcatExprTests.class, 
-                XsDurationComponentExtractionFunctionTests.class, XPathArithmeticOnDurationValuesTests.class,
-                NodeComparisonTests.class, SimpleMapOperatorTests.class, FnFoldLeftTests.class,
-                FnFoldRightTests.class, FnForEachPairTests.class, FnSortTests.class, FnCodepointsToStringTests.class,
-                FnStringToCodepointsTests.class, FnCompareTests.class, FnCodepointEqualTests.class,
-                SequenceFunctionTests.class, FnParseXmlTests.class, FnParseXmlFragmentTests.class,
-                TemplateTests.class, FnAvgTests.class, FnMaxTests.class, FnMinTests.class, FnContainsTokenTests.class,
-                XslVariableAttributeAsTests.class, InstanceOfExprTests.class, XslTemplateAttributeAsTests.class,
-                XslFunctionTests.class, FnRoundTests.class, XslSequenceInstTests.class, FnDocTests.class,
-                FnDataTests.class })
+@SuiteClasses({ Xsl3TestSuite1.class, Xsl3TestSuite2.class})
 public class AllXsl3Tests {
 
 }
diff --git a/tests/org/apache/xalan/xslt3/RecursiveFunctionTests.java b/tests/org/apache/xalan/xslt3/RecursiveFunctionTests.java
new file mode 100644
index 00000000..7235ede7
--- /dev/null
+++ b/tests/org/apache/xalan/xslt3/RecursiveFunctionTests.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.xalan.xslt3;
+
+import org.apache.xalan.util.XslTransformTestsUtil;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * XSLT 3.0 stylesheet test cases, to test recursive 
+ * XSLT and XPath function calls.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class RecursiveFunctionTests extends XslTransformTestsUtil {
+    
+    private static final String XSL_TRANSFORM_INPUT_DIRPATH = XSLConstants.XSL_TRANSFORM_INPUT_DIRPATH_PREFIX + "xsl_recursion/";
+    
+    private static final String XSL_TRANSFORM_GOLD_DIRPATH = XSLConstants.XSL_TRANSFORM_GOLD_DIRPATH_PREFIX + "xsl_recursion/gold/";      
+
+
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        // no op
+    }
+
+    @AfterClass
+    public static void tearDownAfterClass() throws Exception {
+        xmlDocumentBuilderFactory = null;
+        xmlDocumentBuilder = null;
+        xslTransformerFactory = null;
+    }
+    
+    @Test
+    public void xslRecursiveFunctionTest1() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test1.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslRecursiveFunctionTest2() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test2.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+
+    @Test
+    public void xslRecursiveFunctionTest3() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test3.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test3.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test1.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslRecursiveFunctionTest4() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test4.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test4.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test4.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslRecursiveFunctionTest5() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test5.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test5.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslRecursiveFunctionTest6() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test6.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test6.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslRecursiveFunctionTest7() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test7.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test7.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+
+}
diff --git a/tests/org/apache/xalan/xslt3/Xsl3TestSuite1.java b/tests/org/apache/xalan/xslt3/Xsl3TestSuite1.java
new file mode 100644
index 00000000..37991e0f
--- /dev/null
+++ b/tests/org/apache/xalan/xslt3/Xsl3TestSuite1.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.xalan.xslt3;
+
+import org.apache.xalan.xpath3.FnDataTests;
+import org.apache.xalan.xpath3.FnDocTests;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+/**
+ * A JUnit 4 test suite, for XSLT 3.0 and XPath 3.1 tests.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+@RunWith(Suite.class)
+@SuiteClasses({ FnDocTests.class, FnDataTests.class, RecursiveFunctionTests.class })
+public class Xsl3TestSuite1 {
+
+}
diff --git a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java b/tests/org/apache/xalan/xslt3/Xsl3TestSuite2.java
similarity index 92%
copy from tests/org/apache/xalan/xslt3/AllXsl3Tests.java
copy to tests/org/apache/xalan/xslt3/Xsl3TestSuite2.java
index aede2310..214302b3 100644
--- a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
+++ b/tests/org/apache/xalan/xslt3/Xsl3TestSuite2.java
@@ -24,9 +24,7 @@ import org.apache.xalan.xpath3.FnCodepointEqualTests;
 import org.apache.xalan.xpath3.FnCodepointsToStringTests;
 import org.apache.xalan.xpath3.FnCompareTests;
 import org.apache.xalan.xpath3.FnContainsTokenTests;
-import org.apache.xalan.xpath3.FnDataTests;
 import org.apache.xalan.xpath3.FnDistinctValuesTests;
-import org.apache.xalan.xpath3.FnDocTests;
 import org.apache.xalan.xpath3.FnFilterTests;
 import org.apache.xalan.xpath3.FnFoldLeftTests;
 import org.apache.xalan.xpath3.FnFoldRightTests;
@@ -73,11 +71,6 @@ import org.junit.runners.Suite.SuiteClasses;
  * 
  * @xsl.usage advanced
  */
-/*
- *  For all the XSLT and XPath tests supported by this test suite, 
- *  the XSLT transformation expected output files (i.e, the gold files) are 
- *  sensitive to the whitespace contents available within those files.
- */
 @RunWith(Suite.class)
 @SuiteClasses({ AnalyzeStringTests.class, AttributeTests.class, GroupingTests.class,
                 GroupingWithSortTests.class, RtfMigrationTests.class, QuantifiedExprTests.class, 
@@ -97,8 +90,7 @@ import org.junit.runners.Suite.SuiteClasses;
                 SequenceFunctionTests.class, FnParseXmlTests.class, FnParseXmlFragmentTests.class,
                 TemplateTests.class, FnAvgTests.class, FnMaxTests.class, FnMinTests.class, FnContainsTokenTests.class,
                 XslVariableAttributeAsTests.class, InstanceOfExprTests.class, XslTemplateAttributeAsTests.class,
-                XslFunctionTests.class, FnRoundTests.class, XslSequenceInstTests.class, FnDocTests.class,
-                FnDataTests.class })
-public class AllXsl3Tests {
+                XslFunctionTests.class, FnRoundTests.class, XslSequenceInstTests.class })
+public class Xsl3TestSuite2 {
 
 }
diff --git a/tests/xsl_recursion/gold/test1.out b/tests/xsl_recursion/gold/test1.out
new file mode 100644
index 00000000..33530963
--- /dev/null
+++ b/tests/xsl_recursion/gold/test1.out
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>false</one>
+  <two>true</two>
+</result>
diff --git a/tests/xsl_recursion/gold/test2.out b/tests/xsl_recursion/gold/test2.out
new file mode 100644
index 00000000..9f9a830b
--- /dev/null
+++ b/tests/xsl_recursion/gold/test2.out
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <nums isEven="false">
+    <num val="1"/>
+    <num val="3"/>
+    <num val="5"/>
+    <num val="7"/>
+    <num val="9"/>
+    <num val="11"/>
+    <num val="13"/>
+    <num val="15"/>
+  </nums>
+  <nums isEven="true">
+    <num val="2"/>
+    <num val="4"/>
+    <num val="6"/>
+    <num val="8"/>
+    <num val="10"/>
+    <num val="12"/>
+    <num val="14"/>
+  </nums>
+</result>
diff --git a/tests/xsl_recursion/gold/test3.out b/tests/xsl_recursion/gold/test3.out
new file mode 100644
index 00000000..33530963
--- /dev/null
+++ b/tests/xsl_recursion/gold/test3.out
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>false</one>
+  <two>true</two>
+</result>
diff --git a/tests/xsl_recursion/gold/test4.out b/tests/xsl_recursion/gold/test4.out
new file mode 100644
index 00000000..9f9a830b
--- /dev/null
+++ b/tests/xsl_recursion/gold/test4.out
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <nums isEven="false">
+    <num val="1"/>
+    <num val="3"/>
+    <num val="5"/>
+    <num val="7"/>
+    <num val="9"/>
+    <num val="11"/>
+    <num val="13"/>
+    <num val="15"/>
+  </nums>
+  <nums isEven="true">
+    <num val="2"/>
+    <num val="4"/>
+    <num val="6"/>
+    <num val="8"/>
+    <num val="10"/>
+    <num val="12"/>
+    <num val="14"/>
+  </nums>
+</result>
diff --git a/tests/xsl_recursion/gold/test5.out b/tests/xsl_recursion/gold/test5.out
new file mode 100644
index 00000000..33530963
--- /dev/null
+++ b/tests/xsl_recursion/gold/test5.out
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>false</one>
+  <two>true</two>
+</result>
diff --git a/tests/xsl_recursion/gold/test6.out b/tests/xsl_recursion/gold/test6.out
new file mode 100644
index 00000000..9f9a830b
--- /dev/null
+++ b/tests/xsl_recursion/gold/test6.out
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <nums isEven="false">
+    <num val="1"/>
+    <num val="3"/>
+    <num val="5"/>
+    <num val="7"/>
+    <num val="9"/>
+    <num val="11"/>
+    <num val="13"/>
+    <num val="15"/>
+  </nums>
+  <nums isEven="true">
+    <num val="2"/>
+    <num val="4"/>
+    <num val="6"/>
+    <num val="8"/>
+    <num val="10"/>
+    <num val="12"/>
+    <num val="14"/>
+  </nums>
+</result>
diff --git a/tests/xsl_recursion/gold/test7.out b/tests/xsl_recursion/gold/test7.out
new file mode 100644
index 00000000..9f9a830b
--- /dev/null
+++ b/tests/xsl_recursion/gold/test7.out
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <nums isEven="false">
+    <num val="1"/>
+    <num val="3"/>
+    <num val="5"/>
+    <num val="7"/>
+    <num val="9"/>
+    <num val="11"/>
+    <num val="13"/>
+    <num val="15"/>
+  </nums>
+  <nums isEven="true">
+    <num val="2"/>
+    <num val="4"/>
+    <num val="6"/>
+    <num val="8"/>
+    <num val="10"/>
+    <num val="12"/>
+    <num val="14"/>
+  </nums>
+</result>
diff --git a/tests/grouping/test26.xsl b/tests/xsl_recursion/test1.xsl
similarity index 52%
copy from tests/grouping/test26.xsl
copy to tests/xsl_recursion/test1.xsl
index 7d6623c9..e2dcd851 100644
--- a/tests/grouping/test26.xsl
+++ b/tests/xsl_recursion/test1.xsl
@@ -4,25 +4,33 @@
                 version="3.0">
                 
   <!-- Author: mukulg@apache.org -->
-   
-  <!-- use with test1_h.xml -->
   
-  <!-- An XSLT stylesheet to test, xsl:for-each-group instruction. Within this
-       stylesheet example, from an XML input document, all "part" elements are
-       transformed into two groups, with one group having part's expiryDate
-       xs:date value less than current date, and remaining XML "part" elements
-       are put into the second group.    
+  <!-- An XSLT stylesheet test case, to test mutual recursion
+       between two XPath 3.1 function item expressions.
+       
+       The mutual recursion algorithm of the two XPath function item
+       expressions, as mentioned within this stylesheet, has been shared by 
+       Dimitre Novatchev (ref, https://dnovatchev.wordpress.com/2023/10/04/mutual-recursion-with-anonymous-inline-functions-in-xpath-3/).
   -->                
                 
   <xsl:output method="xml" indent="yes"/>
   
-  <xsl:template match="/parts">     
+  <xsl:variable name="isEven" select="function($n as xs:integer) as xs:boolean { 
+                                                          if ($n eq 0) then true() 
+                                                                          else $isOdd($n - 1) }"/>
+  
+  <xsl:variable name="isOdd" select="function($n as xs:integer) as xs:boolean { 
+                                                          if ($n eq 0) then false() 
+                                                                          else $isEven($n - 1) }"/>
+  
+  <xsl:template match="/">     
      <result>
-       <xsl:for-each-group select="part" group-by="xs:date(expiryDate) lt current-date()">
-          <PARTS expired="{current-grouping-key()}">           
-             <xsl:copy-of select="current-group()"/>
-          </PARTS>
-       </xsl:for-each-group>
+       <one>
+         <xsl:value-of select="$isEven(255)"/>
+       </one>
+       <two>
+         <xsl:value-of select="$isOdd(255)"/>       
+       </two>
      </result>
   </xsl:template>
   
diff --git a/tests/xsl_recursion/test1_a.xml b/tests/xsl_recursion/test1_a.xml
new file mode 100644
index 00000000..3341491b
--- /dev/null
+++ b/tests/xsl_recursion/test1_a.xml
@@ -0,0 +1,5 @@
+<info>
+  <val>255</val>
+  <from>1</from>
+  <to>15</to>
+</info>
\ No newline at end of file
diff --git a/tests/xsl_recursion/test2.xsl b/tests/xsl_recursion/test2.xsl
new file mode 100644
index 00000000..fd5ce1bc
--- /dev/null
+++ b/tests/xsl_recursion/test2.xsl
@@ -0,0 +1,72 @@
+<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">
+                
+  <!-- Author: mukulg@apache.org -->
+  
+  <!-- An XSLT stylesheet test case, to test mutual recursion
+       between two XPath 3.1 function item expressions.
+       
+       This stylesheet also performs a loop, and does XSLT
+       grouping of an XML intermediate fragment data set.
+  -->                
+                
+  <xsl:output method="xml" indent="yes"/>
+  
+  <xsl:variable name="isEven" select="function($n as xs:integer) as xs:boolean { 
+                                                                             if ($n eq 0) then true() 
+                                                                                             else $isOdd($n - 1) }"/>
+  
+  <xsl:variable name="isOdd" select="function($n as xs:integer) as xs:boolean { 
+                                                                            if ($n eq 0) then false() 
+                                                                                            else $isEven($n - 1) }"/>
+  
+  <xsl:template match="/">     
+     <result>
+       <xsl:call-template name="analyzeNumsAndMakeGroups">
+         <xsl:with-param name="from" select="1" as="xs:integer"/>
+         <xsl:with-param name="to" select="15" as="xs:integer"/>
+       </xsl:call-template>
+     </result>
+  </xsl:template>
+
+  <xsl:template name="analyzeNumsAndMakeGroups" as="element(nums)*">
+     <xsl:param name="from" as="xs:integer"/>
+     <xsl:param name="to" as="xs:integer"/>
+     <xsl:variable name="numsResult">
+        <xsl:for-each select="$from to $to">
+           <xsl:variable name="num" select="."/>
+           <num val="{$num}" isEven="{$isEven($num)}"/>
+        </xsl:for-each>
+     </xsl:variable>
+     <xsl:for-each-group select="$numsResult/num" group-by="@isEven">
+        <nums isEven="{current-grouping-key()}">
+          <xsl:apply-templates select="current-group()"/>
+        </nums>
+     </xsl:for-each-group>
+  </xsl:template>
+  
+  <xsl:template match="num">
+    <num val="{@val}"/>
+  </xsl:template>
+  
+  <!--
+      * Licensed to the Apache Software Foundation (ASF) under one
+      * or more contributor license agreements. See the NOTICE file
+      * distributed with this work for additional information
+      * regarding copyright ownership. The ASF licenses this file
+      * to you under the Apache License, Version 2.0 (the  "License");
+      * you may not use this file except in compliance with the License.
+      * You may obtain a copy of the License at
+      *
+      *     http://www.apache.org/licenses/LICENSE-2.0
+      *
+      * Unless required by applicable law or agreed to in writing, software
+      * distributed under the License is distributed on an "AS IS" BASIS,
+      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      * See the License for the specific language governing permissions and
+      * limitations under the License.
+  -->
+
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/tests/grouping/test26.xsl b/tests/xsl_recursion/test3.xsl
similarity index 56%
copy from tests/grouping/test26.xsl
copy to tests/xsl_recursion/test3.xsl
index 7d6623c9..c1b9c4de 100644
--- a/tests/grouping/test26.xsl
+++ b/tests/xsl_recursion/test3.xsl
@@ -1,31 +1,40 @@
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                 xmlns:xs="http://www.w3.org/2001/XMLSchema"
-                exclude-result-prefixes="xs"
+                xmlns:fn0="http://fn0"
+                exclude-result-prefixes="xs fn0"
                 version="3.0">
                 
   <!-- Author: mukulg@apache.org -->
-   
-  <!-- use with test1_h.xml -->
   
-  <!-- An XSLT stylesheet to test, xsl:for-each-group instruction. Within this
-       stylesheet example, from an XML input document, all "part" elements are
-       transformed into two groups, with one group having part's expiryDate
-       xs:date value less than current date, and remaining XML "part" elements
-       are put into the second group.    
-  -->                
+  <!-- An XSLT stylesheet test case, to test mutual recursion
+       between two XSLT stylesheet functions.
+  -->                 
                 
   <xsl:output method="xml" indent="yes"/>
   
-  <xsl:template match="/parts">     
+  <xsl:template match="/">     
      <result>
-       <xsl:for-each-group select="part" group-by="xs:date(expiryDate) lt current-date()">
-          <PARTS expired="{current-grouping-key()}">           
-             <xsl:copy-of select="current-group()"/>
-          </PARTS>
-       </xsl:for-each-group>
+       <one>
+         <xsl:value-of select="fn0:isEven(255)"/>
+       </one>
+       <two>
+         <xsl:value-of select="fn0:isOdd(255)"/>       
+       </two>
      </result>
   </xsl:template>
   
+  <xsl:function name="fn0:isEven" as="xs:boolean">
+     <xsl:param name="num" as="xs:integer"/>
+     <xsl:sequence select="if ($num eq 0) then true() 
+                                             else fn0:isOdd($num - 1)"/>
+  </xsl:function>
+  
+  <xsl:function name="fn0:isOdd" as="xs:boolean">
+     <xsl:param name="num" as="xs:integer"/>
+     <xsl:sequence select="if ($num eq 0) then false() 
+                                             else fn0:isEven($num - 1)"/>  
+  </xsl:function>
+  
   <!--
       * Licensed to the Apache Software Foundation (ASF) under one
       * or more contributor license agreements. See the NOTICE file
diff --git a/tests/xsl_recursion/test4.xsl b/tests/xsl_recursion/test4.xsl
new file mode 100644
index 00000000..9fc099c4
--- /dev/null
+++ b/tests/xsl_recursion/test4.xsl
@@ -0,0 +1,77 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                xmlns:fn0="http://fn0"
+                exclude-result-prefixes="xs fn0"
+                version="3.0">
+                
+  <!-- Author: mukulg@apache.org -->
+  
+  <!-- An XSLT stylesheet test case, to test mutual recursion
+       between two XSLT stylesheet functions.
+       
+       This stylesheet also performs a loop, and does XSLT
+       grouping of an XML intermediate fragment data set.
+  -->                
+                
+  <xsl:output method="xml" indent="yes"/>
+  
+  <xsl:template match="/">     
+     <result>
+       <xsl:call-template name="analyzeNumsAndMakeGroups">
+         <xsl:with-param name="from" select="1" as="xs:integer"/>
+         <xsl:with-param name="to" select="15" as="xs:integer"/>
+       </xsl:call-template>
+     </result>
+  </xsl:template>
+
+  <xsl:template name="analyzeNumsAndMakeGroups" as="element(nums)*">
+     <xsl:param name="from" as="xs:integer"/>
+     <xsl:param name="to" as="xs:integer"/>
+     <xsl:variable name="numsResult">
+        <xsl:for-each select="$from to $to">
+           <xsl:variable name="num" select="."/>
+           <num val="{$num}" isEven="{fn0:isEven($num)}"/>
+        </xsl:for-each>
+     </xsl:variable>
+     <xsl:for-each-group select="$numsResult/num" group-by="@isEven">
+        <nums isEven="{current-grouping-key()}">
+          <xsl:apply-templates select="current-group()"/>
+        </nums>
+     </xsl:for-each-group>
+  </xsl:template>
+  
+  <xsl:template match="num">
+    <num val="{@val}"/>
+  </xsl:template>
+  
+  <xsl:function name="fn0:isEven" as="xs:boolean">
+    <xsl:param name="num" as="xs:integer"/>
+    <xsl:sequence select="if ($num eq 0) then true() 
+                                            else fn0:isOdd($num - 1)"/>
+  </xsl:function>
+    
+  <xsl:function name="fn0:isOdd" as="xs:boolean">
+    <xsl:param name="num" as="xs:integer"/>
+    <xsl:sequence select="if ($num eq 0) then false() 
+                                            else fn0:isEven($num - 1)"/>  
+  </xsl:function>
+  
+  <!--
+      * Licensed to the Apache Software Foundation (ASF) under one
+      * or more contributor license agreements. See the NOTICE file
+      * distributed with this work for additional information
+      * regarding copyright ownership. The ASF licenses this file
+      * to you under the Apache License, Version 2.0 (the  "License");
+      * you may not use this file except in compliance with the License.
+      * You may obtain a copy of the License at
+      *
+      *     http://www.apache.org/licenses/LICENSE-2.0
+      *
+      * Unless required by applicable law or agreed to in writing, software
+      * distributed under the License is distributed on an "AS IS" BASIS,
+      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      * See the License for the specific language governing permissions and
+      * limitations under the License.
+  -->
+
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/tests/grouping/test26.xsl b/tests/xsl_recursion/test5.xsl
similarity index 51%
copy from tests/grouping/test26.xsl
copy to tests/xsl_recursion/test5.xsl
index 7d6623c9..72d5746d 100644
--- a/tests/grouping/test26.xsl
+++ b/tests/xsl_recursion/test5.xsl
@@ -4,25 +4,35 @@
                 version="3.0">
                 
   <!-- Author: mukulg@apache.org -->
-   
-  <!-- use with test1_h.xml -->
   
-  <!-- An XSLT stylesheet to test, xsl:for-each-group instruction. Within this
-       stylesheet example, from an XML input document, all "part" elements are
-       transformed into two groups, with one group having part's expiryDate
-       xs:date value less than current date, and remaining XML "part" elements
-       are put into the second group.    
+  <!-- use with test1_a.xml -->
+  
+  <!-- An XSLT stylesheet test case, to test mutual recursion
+       between two XPath 3.1 function item expressions.
+       
+       The mutual recursion algorithm of the two XPath function item
+       expressions, as mentioned within this stylesheet, has been shared by 
+       Dimitre Novatchev (ref, https://dnovatchev.wordpress.com/2023/10/04/mutual-recursion-with-anonymous-inline-functions-in-xpath-3/).
   -->                
                 
   <xsl:output method="xml" indent="yes"/>
   
-  <xsl:template match="/parts">     
+  <xsl:variable name="isEven" select="function($n as xs:integer) as xs:boolean { 
+                                                          if ($n eq 0) then true() 
+                                                                          else $isOdd($n - 1) }"/>
+  
+  <xsl:variable name="isOdd" select="function($n as xs:integer) as xs:boolean { 
+                                                          if ($n eq 0) then false() 
+                                                                          else $isEven($n - 1) }"/>
+  
+  <xsl:template match="/info">     
      <result>
-       <xsl:for-each-group select="part" group-by="xs:date(expiryDate) lt current-date()">
-          <PARTS expired="{current-grouping-key()}">           
-             <xsl:copy-of select="current-group()"/>
-          </PARTS>
-       </xsl:for-each-group>
+       <one>
+         <xsl:value-of select="$isEven(xs:integer(val))"/>
+       </one>
+       <two>
+         <xsl:value-of select="$isOdd(xs:integer(val))"/>       
+       </two>
      </result>
   </xsl:template>
   
diff --git a/tests/xsl_recursion/test6.xsl b/tests/xsl_recursion/test6.xsl
new file mode 100644
index 00000000..7dbcb8f1
--- /dev/null
+++ b/tests/xsl_recursion/test6.xsl
@@ -0,0 +1,74 @@
+<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">
+                
+  <!-- Author: mukulg@apache.org -->
+  
+  <!-- use with test1_a.xml -->
+  
+  <!-- An XSLT stylesheet test case, to test mutual recursion
+       between two XPath 3.1 function item expressions.
+       
+       This stylesheet also performs a loop, and does XSLT
+       grouping of an XML intermediate fragment data set.
+  -->                
+                
+  <xsl:output method="xml" indent="yes"/>
+  
+  <xsl:variable name="isEven" select="function($n as xs:integer) as xs:boolean { 
+                                                          if ($n eq 0) then true() 
+                                                                          else $isOdd($n - 1) }"/>
+  
+  <xsl:variable name="isOdd" select="function($n as xs:integer) as xs:boolean { 
+                                                          if ($n eq 0) then false() 
+                                                                          else $isEven($n - 1) }"/>
+  
+  <xsl:template match="/info">     
+     <result>
+       <xsl:call-template name="analyzeNumsAndMakeGroups">
+         <xsl:with-param name="from" select="xs:integer(from)"/>
+         <xsl:with-param name="to" select="xs:integer(to)"/>
+       </xsl:call-template>
+     </result>
+  </xsl:template>
+
+  <xsl:template name="analyzeNumsAndMakeGroups" as="element(nums)*">
+     <xsl:param name="from" as="xs:integer"/>
+     <xsl:param name="to" as="xs:integer"/>
+     <xsl:variable name="numsResult">
+        <xsl:for-each select="$from to $to">
+           <xsl:variable name="num" select="."/>
+           <num val="{$num}" isEven="{$isEven($num)}"/>
+        </xsl:for-each>
+     </xsl:variable>
+     <xsl:for-each-group select="$numsResult/num" group-by="@isEven">
+        <nums isEven="{current-grouping-key()}">
+          <xsl:apply-templates select="current-group()"/>
+        </nums>
+     </xsl:for-each-group>
+  </xsl:template>
+  
+  <xsl:template match="num">
+    <num val="{@val}"/>
+  </xsl:template>
+  
+  <!--
+      * Licensed to the Apache Software Foundation (ASF) under one
+      * or more contributor license agreements. See the NOTICE file
+      * distributed with this work for additional information
+      * regarding copyright ownership. The ASF licenses this file
+      * to you under the Apache License, Version 2.0 (the  "License");
+      * you may not use this file except in compliance with the License.
+      * You may obtain a copy of the License at
+      *
+      *     http://www.apache.org/licenses/LICENSE-2.0
+      *
+      * Unless required by applicable law or agreed to in writing, software
+      * distributed under the License is distributed on an "AS IS" BASIS,
+      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      * See the License for the specific language governing permissions and
+      * limitations under the License.
+  -->
+
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/tests/xsl_recursion/test7.xsl b/tests/xsl_recursion/test7.xsl
new file mode 100644
index 00000000..357150e0
--- /dev/null
+++ b/tests/xsl_recursion/test7.xsl
@@ -0,0 +1,79 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                xmlns:fn0="http://fn0"
+                exclude-result-prefixes="xs fn0"
+                version="3.0">
+                
+  <!-- Author: mukulg@apache.org -->
+  
+  <!-- use with test1_a.xml -->
+  
+  <!-- An XSLT stylesheet test case, to test mutual recursion
+       between two XSLT stylesheet functions.
+       
+       This stylesheet also performs a loop, and does XSLT
+       grouping of an XML intermediate fragment data set.
+  -->                
+                
+  <xsl:output method="xml" indent="yes"/>
+  
+  <xsl:template match="/info">     
+     <result>
+       <xsl:call-template name="analyzeNumsAndMakeGroups">
+         <xsl:with-param name="from" select="xs:integer(from)"/>
+         <xsl:with-param name="to" select="xs:integer(to)"/>
+       </xsl:call-template>
+     </result>
+  </xsl:template>
+
+  <xsl:template name="analyzeNumsAndMakeGroups" as="element(nums)*">
+     <xsl:param name="from" as="xs:integer"/>
+     <xsl:param name="to" as="xs:integer"/>
+     <xsl:variable name="numsResult">
+        <xsl:for-each select="$from to $to">
+           <xsl:variable name="num" select="."/>
+           <num val="{$num}" isEven="{fn0:isEven($num)}"/>
+        </xsl:for-each>
+     </xsl:variable>
+     <xsl:for-each-group select="$numsResult/num" group-by="@isEven">
+        <nums isEven="{current-grouping-key()}">
+          <xsl:apply-templates select="current-group()"/>
+        </nums>
+     </xsl:for-each-group>
+  </xsl:template>
+  
+  <xsl:template match="num">
+    <num val="{@val}"/>
+  </xsl:template>
+  
+  <xsl:function name="fn0:isEven" as="xs:boolean">
+    <xsl:param name="num" as="xs:integer"/>
+    <xsl:sequence select="if ($num eq 0) then true() 
+                                            else fn0:isOdd($num - 1)"/>
+  </xsl:function>
+    
+  <xsl:function name="fn0:isOdd" as="xs:boolean">
+    <xsl:param name="num" as="xs:integer"/>
+    <xsl:sequence select="if ($num eq 0) then false() 
+                                            else fn0:isEven($num - 1)"/>  
+  </xsl:function>
+  
+  <!--
+      * Licensed to the Apache Software Foundation (ASF) under one
+      * or more contributor license agreements. See the NOTICE file
+      * distributed with this work for additional information
+      * regarding copyright ownership. The ASF licenses this file
+      * to you under the Apache License, Version 2.0 (the  "License");
+      * you may not use this file except in compliance with the License.
+      * You may obtain a copy of the License at
+      *
+      *     http://www.apache.org/licenses/LICENSE-2.0
+      *
+      * Unless required by applicable law or agreed to in writing, software
+      * distributed under the License is distributed on an "AS IS" BASIS,
+      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      * See the License for the specific language governing permissions and
+      * limitations under the License.
+  -->
+
+</xsl:stylesheet>
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xalan.apache.org
For additional commands, e-mail: commits-help@xalan.apache.org