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/06/12 13:31:32 UTC

[xalan-java] branch xalan-j_xslt3.0 updated: implementing xslt 3.0's xsl:on-completion instruction for xsl:iterate. committing few minor related codebase changes as well. also committing few new relevant working test cases.

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 a768cf51 implementing xslt 3.0's xsl:on-completion instruction for xsl:iterate. committing few minor related codebase changes as well. also committing few new relevant working test cases.
a768cf51 is described below

commit a768cf510256a03f70440573664a7b0f022fa10d
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Mon Jun 12 19:01:17 2023 +0530

    implementing xslt 3.0's xsl:on-completion instruction for xsl:iterate. committing few minor related codebase changes as well. also committing few new relevant working test cases.
---
 src/org/apache/xalan/templates/ElemIterate.java    | 28 ++++++++++--
 .../apache/xalan/templates/ElemIterateBreak.java   |  6 +--
 .../xalan/templates/ElemIterateOnCompletion.java   | 52 +++++++++++++++++++--
 .../xslt/util/XslTransformErrorLocatorHelper.java  |  2 +
 src/org/apache/xpath/functions/FuncLast.java       |  7 +++
 src/org/apache/xpath/functions/FuncPosition.java   | 13 +++++-
 tests/org/apache/xalan/xslt3/XslIterateTests.java  | 53 ++++++++++++++++++++++
 tests/xsl_iterate/gold/test4.out                   | 10 ++++
 tests/xsl_iterate/gold/test6.out                   |  1 +
 tests/xsl_iterate/gold/test7.out                   |  0
 tests/xsl_iterate/test4.xsl                        | 42 +++++++++++++++++
 tests/xsl_iterate/test5.xsl                        | 49 ++++++++++++++++++++
 tests/xsl_iterate/test6.xsl                        | 49 ++++++++++++++++++++
 tests/xsl_iterate/test7.xsl                        | 43 ++++++++++++++++++
 tests/xsl_iterate/test8.xsl                        | 43 ++++++++++++++++++
 15 files changed, 383 insertions(+), 15 deletions(-)

diff --git a/src/org/apache/xalan/templates/ElemIterate.java b/src/org/apache/xalan/templates/ElemIterate.java
index cea1e7d3..572c1e6d 100644
--- a/src/org/apache/xalan/templates/ElemIterate.java
+++ b/src/org/apache/xalan/templates/ElemIterate.java
@@ -205,7 +205,10 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
                transformer.pushElemTemplateElement(null);                              
            
                int docID = sourceNode & DTMManager.IDENT_DTM_DEFAULT;
-               int child;               
+               int child;
+               
+               ElemIterateOnCompletion xslOnCompletionTemplate = null;
+               
                while ((child = sourceNodes.nextNode()) != DTM.NULL) {
                    currentNodes.setTop(child);
                    currentExpressionNodes.setTop(child);
@@ -218,6 +221,11 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
                    for (ElemTemplateElement elemTemplate = this.m_firstChild; 
                                                           elemTemplate != null; 
                                                           elemTemplate = elemTemplate.m_nextSibling) {
+                       if ((elemTemplate instanceof ElemIterateOnCompletion) && 
+                                                                        (xslOnCompletionTemplate == null)) {
+                           xslOnCompletionTemplate = (ElemIterateOnCompletion)elemTemplate;     
+                       }
+                       
                        if (!((XslTransformErrorLocatorHelper.isXslIterateBreakEvaluated).booleanValue())) {
                           xctxt.setSAXLocator(elemTemplate);
                           transformer.setCurrentElement(elemTemplate);
@@ -228,11 +236,21 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
                        }
                    }
                    
-                   if ((XslTransformErrorLocatorHelper.isXslIterateBreakEvaluated).booleanValue()) {
-                       XslTransformErrorLocatorHelper.isXslIterateBreakEvaluated = Boolean.FALSE;
+                   if ((XslTransformErrorLocatorHelper.isXslIterateBreakEvaluated).booleanValue()) {                       
                        break;   
                    }
                }
+               
+               if ((xslOnCompletionTemplate != null) && !(XslTransformErrorLocatorHelper.
+                                                                                isXslIterateBreakEvaluated).booleanValue()) {
+                  XslTransformErrorLocatorHelper.isXslIterateOnCompletionActive = Boolean.TRUE;
+                  xctxt.setSAXLocator(xslOnCompletionTemplate);
+                  transformer.setCurrentElement(xslOnCompletionTemplate);
+                  xslOnCompletionTemplate.execute(transformer);
+                  XslTransformErrorLocatorHelper.isXslIterateOnCompletionActive = Boolean.FALSE;
+               }
+               
+               XslTransformErrorLocatorHelper.isXslIterateBreakEvaluated = Boolean.FALSE;
            }
            finally {
               xctxt.popSAXLocator();
@@ -266,7 +284,7 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
                                                                                     equals(elemTemplate.getLocalName()))) {
                   // revisit.
                   // currently, 'elemTemplate instanceof ElemParam' is evaluated as false but 'elemTemplate 
-                  // instanceof ElemUnknown' is evaluated as true within this "if" condition.                  
+                  // instanceof ElemUnknown' is evaluated as true when this "if" condition was evaluated.                  
                   xslElemNamesList.add(Constants.ELEMNAME_PARAMVARIABLE_STRING);
                   
                   // ElemUnknown elemUnknown = (ElemUnknown)elemTemplate;
@@ -286,7 +304,7 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
           }
           
           // get index of specific item's first occurrence with the list object 'xslElemNamesList'.
-          // if a particular kind of item that is checked is not present within the list object 
+          // if a particular kind of xdm item that is checked is not present within the list object 
           // 'xslElemNamesList', its index is returned as -1.
           int paramIdx = xslElemNamesList.indexOf(Constants.ELEMNAME_PARAMVARIABLE_STRING);
           int onCompletionIdx = xslElemNamesList.indexOf(Constants.ELEMNAME_ITERATE_ONCOMPLETION_STRING);
diff --git a/src/org/apache/xalan/templates/ElemIterateBreak.java b/src/org/apache/xalan/templates/ElemIterateBreak.java
index 6ee9ade1..2135d561 100644
--- a/src/org/apache/xalan/templates/ElemIterateBreak.java
+++ b/src/org/apache/xalan/templates/ElemIterateBreak.java
@@ -160,9 +160,9 @@ public class ElemIterateBreak extends ElemTemplateElement implements ExpressionO
                                                                         + "stylesheet element as its following sibling.", 
                                                                                          xpathContext.getSAXLocator());    
            }
-           else {
+           else {              
+              transformXslBreakInstruction(transformer);
               XslTransformErrorLocatorHelper.isXslIterateBreakEvaluated = Boolean.TRUE;
-              transformSelectedNodes(transformer);
            }
        }
 
@@ -173,7 +173,7 @@ public class ElemIterateBreak extends ElemTemplateElement implements ExpressionO
        * 
        * @xsl.usage advanced
        */
-       public void transformSelectedNodes(TransformerImpl transformer) throws 
+       public void transformXslBreakInstruction(TransformerImpl transformer) throws 
                                                                  TransformerException {
            XPathContext xctxt = transformer.getXPathContext();
            
diff --git a/src/org/apache/xalan/templates/ElemIterateOnCompletion.java b/src/org/apache/xalan/templates/ElemIterateOnCompletion.java
index f0968533..3c69b392 100644
--- a/src/org/apache/xalan/templates/ElemIterateOnCompletion.java
+++ b/src/org/apache/xalan/templates/ElemIterateOnCompletion.java
@@ -20,9 +20,15 @@ package org.apache.xalan.templates;
 import javax.xml.transform.TransformerException;
 
 import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xalan.xslt.util.XslTransformErrorLocatorHelper;
+import org.apache.xml.serializer.SerializationHandler;
 import org.apache.xpath.Expression;
 import org.apache.xpath.ExpressionOwner;
 import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.xml.sax.SAXException;
+
+import com.sun.org.apache.xml.internal.dtm.DTM;
 
 /**
  * XSLT 3.0 xsl:on-completion element.
@@ -50,6 +56,8 @@ public class ElemIterateOnCompletion extends ElemTemplateElement implements Expr
       * Construct an element representing xsl:on-completion.
       */
      public ElemIterateOnCompletion() {}
+     
+     private String xpathSelectPatternStr;
 
      /**
       * The "select" expression.
@@ -58,7 +66,8 @@ public class ElemIterateOnCompletion extends ElemTemplateElement implements Expr
 
      public void setSelect(XPath xpath)
      {
-         m_selectExpression = xpath.getExpression();   
+         m_selectExpression = xpath.getExpression();
+         xpathSelectPatternStr = xpath.getPatternString();
      }
 
      /**
@@ -148,7 +157,7 @@ public class ElemIterateOnCompletion extends ElemTemplateElement implements Expr
        */
        public void execute(TransformerImpl transformer) throws TransformerException
        {
-           transformSelectedNodes(transformer);
+           transformXslOncompletionInstruction(transformer);
        }
 
        /**
@@ -158,9 +167,42 @@ public class ElemIterateOnCompletion extends ElemTemplateElement implements Expr
        * 
        * @xsl.usage advanced
        */
-       public void transformSelectedNodes(TransformerImpl transformer) throws 
-                                                                 TransformerException {
-           // TO DO         
+       public void transformXslOncompletionInstruction(TransformerImpl transformer) throws 
+                                                                               TransformerException {
+                                                                  
+           if ((XslTransformErrorLocatorHelper.isXslIterateOnCompletionActive).booleanValue()) {
+               final XPathContext originalXctxt = transformer.getXPathContext();
+               
+               XPathContext xctxt = transformer.getXPathContext();
+               
+               // during evaluation of xsl:on-completion, the context item is absent.
+               // we make following two changes to XPath context to ensure this.
+               xctxt.pushCurrentNode(DTM.NULL);
+               xctxt.pushCurrentExpressionNode(DTM.NULL);
+               
+               if (xpathSelectPatternStr != null) {
+                   SerializationHandler rth = transformer.getResultTreeHandler();
+                   
+                   try {
+                       m_selectExpression.executeCharsToContentHandler(xctxt, rth);
+                   } catch (TransformerException ex) {
+                       throw ex;
+                   } catch (SAXException ex) {
+                       throw new TransformerException(ex);
+                   }
+               }
+               else {
+                   for (ElemTemplateElement elemTemplate = this.m_firstChild; elemTemplate != null; 
+                                                                        elemTemplate = elemTemplate.m_nextSibling) {
+                      xctxt.setSAXLocator(elemTemplate);
+                      transformer.setCurrentElement(elemTemplate);
+                      elemTemplate.execute(transformer);
+                   } 
+               }
+               
+               // restore the XPath original context, on current XSLT transformer object
+               transformer.setXPathContext(originalXctxt);
+           }                      
        }
       
 }
diff --git a/src/org/apache/xalan/xslt/util/XslTransformErrorLocatorHelper.java b/src/org/apache/xalan/xslt/util/XslTransformErrorLocatorHelper.java
index 06ce48d5..9b6399b3 100644
--- a/src/org/apache/xalan/xslt/util/XslTransformErrorLocatorHelper.java
+++ b/src/org/apache/xalan/xslt/util/XslTransformErrorLocatorHelper.java
@@ -30,5 +30,7 @@ public class XslTransformErrorLocatorHelper {
     public static String systemId;
     
     public static Boolean isXslIterateBreakEvaluated = Boolean.FALSE;
+    
+    public static Boolean isXslIterateOnCompletionActive = Boolean.FALSE;
 
 }
diff --git a/src/org/apache/xpath/functions/FuncLast.java b/src/org/apache/xpath/functions/FuncLast.java
index bf3eb9ac..09fae2dc 100644
--- a/src/org/apache/xpath/functions/FuncLast.java
+++ b/src/org/apache/xpath/functions/FuncLast.java
@@ -20,6 +20,7 @@
  */
 package org.apache.xpath.functions;
 
+import org.apache.xml.dtm.DTM;
 import org.apache.xml.dtm.DTMIterator;
 import org.apache.xpath.XPathContext;
 import org.apache.xpath.axes.SubContextList;
@@ -63,6 +64,12 @@ public class FuncLast extends Function
     if (xctxt.getXPath3ContextSize() != -1) {
         return xctxt.getXPath3ContextSize();
     }
+    
+    if (xctxt.getContextNode() == DTM.NULL) {
+        throw new javax.xml.transform.TransformerException("XPDY0002 : The context item is absent "
+                                                                 + "at this point, and therefore last() function "
+                                                                 + "cannot be called.", xctxt.getSAXLocator());       
+    }
 
     // assert(null != m_contextNodeList, "m_contextNodeList must be non-null");
     // If we're in a predicate, then this will return non-null.
diff --git a/src/org/apache/xpath/functions/FuncPosition.java b/src/org/apache/xpath/functions/FuncPosition.java
index b5e6f1a3..36f7c15e 100644
--- a/src/org/apache/xpath/functions/FuncPosition.java
+++ b/src/org/apache/xpath/functions/FuncPosition.java
@@ -20,6 +20,8 @@
  */
 package org.apache.xpath.functions;
 
+import javax.xml.transform.TransformerException;
+
 import org.apache.xml.dtm.DTM;
 import org.apache.xml.dtm.DTMIterator;
 import org.apache.xpath.XPathContext;
@@ -55,14 +57,21 @@ public class FuncPosition extends Function
    *
    * @return The current position of the iteration in the context node list, 
    *         or -1 if there is no active context node list.
+ * @throws TransformerException 
    */
-  public int getPositionInContextNodeList(XPathContext xctxt)
+  public int getPositionInContextNodeList(XPathContext xctxt) throws TransformerException
   {
     
     if (xctxt.getXPath3ContextPosition() != -1) {
        return xctxt.getXPath3ContextPosition();
     }
     
+    if (xctxt.getContextNode() == DTM.NULL) {
+        throw new javax.xml.transform.TransformerException("XPDY0002 : The context item is absent "
+                                                                  + "at this point, and therefore position() function "
+                                                                  + "cannot be called.", xctxt.getSAXLocator());       
+    }
+    
     // System.out.println("FuncPosition- entry");
     // If we're in a predicate, then this will return non-null.
     SubContextList iter = m_isTopLevel ? null : xctxt.getSubContextList();
@@ -124,7 +133,7 @@ public class FuncPosition extends Function
    * @throws javax.xml.transform.TransformerException
    */
   public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
-  {
+  {    
     double pos = (double) getPositionInContextNodeList(xctxt);
     
     return new XNumber(pos);
diff --git a/tests/org/apache/xalan/xslt3/XslIterateTests.java b/tests/org/apache/xalan/xslt3/XslIterateTests.java
index 573fa976..1afec217 100644
--- a/tests/org/apache/xalan/xslt3/XslIterateTests.java
+++ b/tests/org/apache/xalan/xslt3/XslIterateTests.java
@@ -16,6 +16,7 @@
  */
 package org.apache.xalan.xslt3;
 
+import org.apache.xalan.util.XslTestsErrorHandler;
 import org.apache.xalan.util.XslTransformTestsUtil;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -77,5 +78,57 @@ public class XslIterateTests extends XslTransformTestsUtil {
         
         runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
     }
+    
+    @Test
+    public void xslIterateTest4() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test4.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test4.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslIterateTest5() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test5.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test4.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslIterateTest6() {
+        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 xslIterateTest7() {
+        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, 
+                                                            new XslTestsErrorHandler());
+    }
+    
+    @Test
+    public void xslIterateTest8() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test8.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test7.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, 
+                                                            new XslTestsErrorHandler());
+    }
 
 }
diff --git a/tests/xsl_iterate/gold/test4.out b/tests/xsl_iterate/gold/test4.out
new file mode 100644
index 00000000..7c34280d
--- /dev/null
+++ b/tests/xsl_iterate/gold/test4.out
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <item>hello1</item>
+  <item>hello2</item>
+  <item>hello3</item>
+  <item>hello4</item>
+  <item>hello5</item>
+  <item>hello6</item>
+  <item>hello7</item>
+  <allItemsProcessedWithoutBreak/>
+</result>
diff --git a/tests/xsl_iterate/gold/test6.out b/tests/xsl_iterate/gold/test6.out
new file mode 100644
index 00000000..a19077d4
--- /dev/null
+++ b/tests/xsl_iterate/gold/test6.out
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><result/>
diff --git a/tests/xsl_iterate/gold/test7.out b/tests/xsl_iterate/gold/test7.out
new file mode 100644
index 00000000..e69de29b
diff --git a/tests/xsl_iterate/test4.xsl b/tests/xsl_iterate/test4.xsl
new file mode 100644
index 00000000..74dcf787
--- /dev/null
+++ b/tests/xsl_iterate/test4.xsl
@@ -0,0 +1,42 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="3.0">
+                
+  <!-- Author: mukulg@apache.org -->
+   
+  <!-- use with test1_a.xml -->
+  
+  <!-- An XSLT stylesheet test, demonstrating use of xsl:iterate
+       with xsl:on-completion. -->                
+                
+  <xsl:output method="xml" indent="yes"/>                
+
+  <xsl:template match="/elem">
+     <result>
+        <xsl:iterate select="a">
+           <xsl:on-completion>
+	          <allItemsProcessedWithoutBreak/>
+           </xsl:on-completion>
+           <item><xsl:value-of select="."/></item>           
+        </xsl:iterate>
+     </result>
+  </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>
diff --git a/tests/xsl_iterate/test5.xsl b/tests/xsl_iterate/test5.xsl
new file mode 100644
index 00000000..527a851f
--- /dev/null
+++ b/tests/xsl_iterate/test5.xsl
@@ -0,0 +1,49 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="3.0">
+                
+  <!-- Author: mukulg@apache.org -->
+   
+  <!-- use with test1_a.xml -->
+  
+  <!-- An XSLT stylesheet test, demonstrating use of xsl:iterate
+       with xsl:on-completion. -->                 
+                
+  <xsl:output method="xml" indent="yes"/>                
+
+  <xsl:template match="/elem">
+     <result>
+        <xsl:iterate select="a">
+           <xsl:on-completion>
+	          <allItemsProcessedWithoutBreak/>
+           </xsl:on-completion>
+           <xsl:choose>
+              <xsl:when test="true()">
+                 <item><xsl:value-of select="."/></item>
+              </xsl:when>
+              <xsl:otherwise>
+                 <xsl:break/>
+              </xsl:otherwise>
+           </xsl:choose>
+        </xsl:iterate>
+     </result>
+  </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>
diff --git a/tests/xsl_iterate/test6.xsl b/tests/xsl_iterate/test6.xsl
new file mode 100644
index 00000000..abca2daa
--- /dev/null
+++ b/tests/xsl_iterate/test6.xsl
@@ -0,0 +1,49 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="3.0">
+                
+  <!-- Author: mukulg@apache.org -->
+   
+  <!-- use with test1_a.xml -->
+  
+  <!-- An XSLT stylesheet test, demonstrating use of xsl:iterate
+       with xsl:on-completion. -->                
+                
+  <xsl:output method="xml" indent="yes"/>                
+
+  <xsl:template match="/elem">
+     <result>
+        <xsl:iterate select="a">
+           <xsl:on-completion>
+	          <allItemsProcessedWithoutBreak/>
+           </xsl:on-completion>
+           <xsl:choose>
+              <xsl:when test="false()">
+                 <item><xsl:value-of select="."/></item>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:break/>
+              </xsl:otherwise>
+           </xsl:choose>
+        </xsl:iterate>
+     </result>
+  </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>
diff --git a/tests/xsl_iterate/test7.xsl b/tests/xsl_iterate/test7.xsl
new file mode 100644
index 00000000..c0a040e6
--- /dev/null
+++ b/tests/xsl_iterate/test7.xsl
@@ -0,0 +1,43 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="3.0">
+                
+  <!-- Author: mukulg@apache.org -->
+   
+  <!-- use with test1_a.xml -->
+  
+  <!-- An XSLT stylesheet test, that demonstrates, that position()
+       function cannot be called within xsl:on-completion instruction,
+       because within xsl:on-completion 'context item' is absent. -->               
+                
+  <xsl:output method="xml" indent="yes"/>                
+
+  <xsl:template match="/elem">
+     <result>
+        <xsl:iterate select="a">
+           <xsl:on-completion>     
+	          <status><xsl:value-of select="position()"/></status>
+           </xsl:on-completion>
+           <item><xsl:value-of select="."/></item>
+        </xsl:iterate>
+     </result>
+  </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>
diff --git a/tests/xsl_iterate/test8.xsl b/tests/xsl_iterate/test8.xsl
new file mode 100644
index 00000000..8ba5c11b
--- /dev/null
+++ b/tests/xsl_iterate/test8.xsl
@@ -0,0 +1,43 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="3.0">
+                
+  <!-- Author: mukulg@apache.org -->
+   
+  <!-- use with test1_a.xml -->
+  
+  <!-- An XSLT stylesheet test, that demonstrates, that last()
+       function cannot be called within xsl:on-completion instruction,
+       because within xsl:on-completion 'context item' is absent. -->               
+                
+  <xsl:output method="xml" indent="yes"/>                
+
+  <xsl:template match="/elem">
+     <result>
+        <xsl:iterate select="a">
+           <xsl:on-completion>     
+	          <status><xsl:value-of select="last()"/></status>
+           </xsl:on-completion>
+           <item><xsl:value-of select="."/></item>
+        </xsl:iterate>
+     </result>
+  </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>


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