[prev in list] [next in list] [prev in thread] [next in thread] 

List:       xalan-cvs
Subject:    [xalan-java] branch xalan-j_xslt3.0 updated: committing improvements to implementation of xslt 3.0's
From:       mukulg () apache ! org
Date:       2023-09-30 12:11:01
Message-ID: 169607586104.1578415.15610995835305005850 () gitbox2-he-fi ! apache ! org
[Download RAW message or body]

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 0e3d0cae committing improvements to implementation of xslt 3.0's xsl:iterate \
instruction, making it more correct. also committing few new working related test \
                cases.
     new 6c3babb1 Merge pull request #92 from mukulga/xalan-j_xslt3.0_mukul
0e3d0cae is described below

commit 0e3d0cae9c83771f55fb73be4361b3c189cfb3bf
Author: Mukul Gandhi <gandhi.mukul@gmail.com>
AuthorDate: Sat Sep 30 17:36:40 2023 +0530

    committing improvements to implementation of xslt 3.0's xsl:iterate instruction, \
                making it more correct. also committing few new working related test \
                cases.
---
 src/org/apache/xalan/templates/ElemIterate.java    | 297 ++++++++++-----------
 .../apache/xalan/templates/ElemIterateBreak.java   |  20 +-
 .../xalan/templates/ElemIterateNextIteration.java  | 137 +++++++---
 .../xalan/templates/ElemIterateOnCompletion.java   |  41 ++-
 src/org/apache/xalan/templates/ElemParam.java      |  47 ++--
 .../apache/xalan/transformer/TransformerImpl.java  |  26 ++
 .../xslt/util/XslTransformSharedDatastore.java     |   6 -
 tests/org/apache/xalan/xslt3/XslIterateTests.java  |  40 +++
 tests/xsl_iterate/gold/test23.out                  |   4 +
 tests/xsl_iterate/gold/test24.out                  |   9 +
 tests/xsl_iterate/gold/test25.out                  |   4 +
 tests/xsl_iterate/gold/test26.out                  |   9 +
 tests/xsl_iterate/test1_g.xml                      |   4 +
 tests/xsl_iterate/test23.xsl                       |  64 +++++
 tests/xsl_iterate/test24.xsl                       |  72 +++++
 tests/xsl_iterate/test25.xsl                       |  69 +++++
 tests/xsl_iterate/test26.xsl                       |  75 ++++++
 17 files changed, 666 insertions(+), 258 deletions(-)

diff --git a/src/org/apache/xalan/templates/ElemIterate.java \
b/src/org/apache/xalan/templates/ElemIterate.java index 62765e9a..8e767d36 100644
--- a/src/org/apache/xalan/templates/ElemIterate.java
+++ b/src/org/apache/xalan/templates/ElemIterate.java
@@ -23,7 +23,6 @@ import java.util.List;
 import javax.xml.transform.TransformerException;
 
 import org.apache.xalan.transformer.TransformerImpl;
-import org.apache.xalan.xslt.util.XslTransformSharedDatastore;
 import org.apache.xml.dtm.DTM;
 import org.apache.xml.dtm.DTMIterator;
 import org.apache.xml.utils.IntStack;
@@ -32,42 +31,19 @@ import org.apache.xpath.Expression;
 import org.apache.xpath.ExpressionOwner;
 import org.apache.xpath.XPath;
 import org.apache.xpath.XPathContext;
-import org.apache.xpath.functions.DynamicFunctionCall;
-import org.apache.xpath.functions.Function;
 import org.apache.xpath.objects.ResultSequence;
 import org.apache.xpath.objects.XNodeSet;
 import org.apache.xpath.objects.XObject;
-import org.apache.xpath.operations.Operation;
-import org.apache.xpath.operations.Variable;
 
-/**
- * XSLT 3.0 xsl:iterate element.
+/*
+ * Implementation of the XSLT 3.0 xsl:iterate instruction.
  * 
-   <xsl:iterate select = expression>
-      <!-- Content: (xsl:param*, xsl:on-completion?, sequence-constructor) -->
-   </xsl:iterate>
-   
-   <xsl:next-iteration>
-      <!-- Content: (xsl:with-param*) -->
-   </xsl:next-iteration>
-
-   <xsl:break select? = expression>
-      <!-- Content: sequence-constructor -->
-   </xsl:break>
-
-   <xsl:on-completion select? = expression>
-      <!-- Content: sequence-constructor -->
-   </xsl:on-completion>
-   
-   Ref : https://www.w3.org/TR/xslt-30/#iterate
-         
-   @author Mukul Gandhi <mukulg@apache.org>
+ * Ref : https://www.w3.org/TR/xslt-30/#element-iterate
+ * 
+ * @author Mukul Gandhi <mukulg@apache.org>
  * 
  * @xsl.usage advanced
  */
-/*
- * Implementation of the XSLT 3.0 xsl:iterate instruction.
- */
 public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
 {
 
@@ -190,9 +166,7 @@ public class ElemIterate extends ElemTemplateElement implements \
                ExpressionOwner
        * 
        * @xsl.usage advanced
        */
-       public void transformSelectedNodes(TransformerImpl transformer) throws \
                TransformerException {
-    
-           final XPathContext xctxtOriginal = transformer.getXPathContext();
+       private void transformSelectedNodes(TransformerImpl transformer) throws \
TransformerException {  
            XPathContext xctxt = transformer.getXPathContext();
          
@@ -202,154 +176,163 @@ public class ElemIterate extends ElemTemplateElement \
implements ExpressionOwner  // instruction's evaluation.
            fXslIterateParamWithparamDataList.clear();
            
-           validateXslElemIterateChildElementsSequence(xctxt);
-           
-           // Evaluate xsl:iterate instruction, when value of its "select" attribute \
                evaluates 
-           // to a 'ResultSequence'. 
-           if ((m_selectExpression instanceof Variable) || 
-                                                  (m_selectExpression instanceof \
                Operation) || 
-                                                  (m_selectExpression instanceof \
                Function)  ||
-                                                  (m_selectExpression instanceof \
DynamicFunctionCall)) { +           \
validateXslElemIterateChildElementsSequence(xctxt);   
-               XObject  evalResult = m_selectExpression.execute(xctxt);
+           XObject evalResult = m_selectExpression.execute(xctxt);                   \
  
-               if (evalResult instanceof ResultSequence) {
-                   ResultSequence resultSeq = (ResultSequence)evalResult;
-                   List<XObject> resultSeqItems = \
resultSeq.getResultSequenceItems();                                       +           \
if (evalResult instanceof ResultSequence) { +               ResultSequence resultSeq \
= (ResultSequence)evalResult; +               List<XObject> resultSeqItems = \
resultSeq.getResultSequenceItems();                                        
-                   ElemIterateOnCompletion xslOnCompletionTemplate = null;
+               ElemIterateOnCompletion xslOnCompletionTemplate = null;
                    
-                   for (int idx = 0; idx < resultSeqItems.size(); idx++) {
-                       XObject resultSeqItem = resultSeqItems.get(idx);
-                       
-                       if (resultSeqItem instanceof XNodeSet) {
-                          resultSeqItem = ((XNodeSet)resultSeqItem).getFresh(); 
-                       }
-                       
-                       \
setXPathContextForXslSequenceProcessing(resultSeqItems.size(), idx, resultSeqItem, \
                xctxt);
-                       
-                       boolean isBreakFromXslContentLoop = false;
+               boolean isBreakFromXslContentLoop = false;
+                   
+               for (int idx = 0; idx < resultSeqItems.size(); idx++) {
+                  XObject resultSeqItem = resultSeqItems.get(idx);
                        
-                       for (ElemTemplateElement elemTemplate = this.m_firstChild; \
                elemTemplate != null; 
-                                                                             \
                elemTemplate = elemTemplate.m_nextSibling) {
-                           if ((elemTemplate instanceof ElemIterateOnCompletion) && \
                (xslOnCompletionTemplate == null)) {
-                               xslOnCompletionTemplate = \
                (ElemIterateOnCompletion)elemTemplate;     
-                           }
-                           
-                           if \
                (!(XslTransformSharedDatastore.isXslIterateBreakEvaluated).booleanValue()) \
                {
-                               xctxt.setSAXLocator(elemTemplate);
-                               transformer.setCurrentElement(elemTemplate);
-                               elemTemplate.execute(transformer);
-                           }
-                           else {                              
-                               \
resetXPathContextForXslSequenceProcessing(resultSeqItem, xctxt);                      \
                
-                               isBreakFromXslContentLoop = true;                     \
                
-                               break;    
-                           }
-                       }
+                  if (resultSeqItem instanceof XNodeSet) {
+                     resultSeqItem = ((XNodeSet)resultSeqItem).getFresh(); 
+                  }
                        
-                       if (!isBreakFromXslContentLoop) {                         
-                          resetXPathContextForXslSequenceProcessing(resultSeqItem, \
                xctxt);
-                       }
+                  setXPathContextForXslSequenceProcessing(resultSeqItems.size(), \
idx, resultSeqItem, xctxt); +                                                         \
 +                  for (ElemTemplateElement elemTemplate = this.m_firstChild; \
elemTemplate != null;  +                                                              \
elemTemplate = elemTemplate.m_nextSibling) {                            +             \
if (idx == 0) { +                          if (elemTemplate instanceof ElemParam) {
+                              // For xsl:iterate's first iteration, evaluate \
xsl:param element +                              xctxt.setSAXLocator(elemTemplate);
+                              transformer.setCurrentElement(elemTemplate);
+                              \
((ElemParam)elemTemplate).setXslIterateIterationIdx(idx); +                           \
elemTemplate.execute(transformer); +                          }                       \
 +                          else if (elemTemplate instanceof ElemIterateOnCompletion) \
{ +                              xslOnCompletionTemplate = \
(ElemIterateOnCompletion)elemTemplate; +                          }
+                          else {
+                             if (!transformer.isXslIterateBreakEvaluated()) {
+                                xctxt.setSAXLocator(elemTemplate);
+                                transformer.setCurrentElement(elemTemplate);
+                                elemTemplate.execute(transformer);
+                             }
+                             else {                              
+                                \
resetXPathContextForXslSequenceProcessing(resultSeqItem, xctxt);                      \
 +                                isBreakFromXslContentLoop = true;                   \
 +                                break;    
+                             }
+                          }
+                      }
+                      else {
+                          if (!transformer.isXslIterateBreakEvaluated()) {
+                             xctxt.setSAXLocator(elemTemplate);
+                             transformer.setCurrentElement(elemTemplate);
+                             elemTemplate.execute(transformer);
+                          }
+                          else {                              
+                             \
resetXPathContextForXslSequenceProcessing(resultSeqItem, xctxt);                      \
 +                             isBreakFromXslContentLoop = true;                      \
 +                             break;    
+                          }
+                      }
+                  }
                        
-                       if \
((XslTransformSharedDatastore.isXslIterateBreakEvaluated).booleanValue()) {           \
                
-                          break;   
-                       }
-                   }
+                  if (!isBreakFromXslContentLoop) {                         
+                     resetXPathContextForXslSequenceProcessing(resultSeqItem, \
xctxt);   +                  }
+                  else {                          
+                     break;
+                  }
+               }
                    
-                   // Reset the, XPath context's size, item and position variables
-                   xctxt.setXPath3ContextSize(-1);
-                   xctxt.setXPath3ContextItem(null);
-                   xctxt.setXPath3ContextPosition(-1);                               \
 +               // Reset the, XPath context's size, item and position variables
+               xctxt.setXPath3ContextSize(-1);
+               xctxt.setXPath3ContextItem(null);
+               xctxt.setXPath3ContextPosition(-1);                                   \
  
-                   if ((xslOnCompletionTemplate != null) && \
                !(XslTransformSharedDatastore.
-                                                                              \
                isXslIterateBreakEvaluated).booleanValue()) {
-                        XslTransformSharedDatastore.isXslIterateOnCompletionActive = \
                Boolean.TRUE;
-                        xctxt.setSAXLocator(xslOnCompletionTemplate);
-                        transformer.setCurrentElement(xslOnCompletionTemplate);
-                        xslOnCompletionTemplate.execute(transformer);
-                        XslTransformSharedDatastore.isXslIterateOnCompletionActive = \
                Boolean.FALSE;
-                  }
-
-                  XslTransformSharedDatastore.isXslIterateBreakEvaluated = \
                Boolean.FALSE;
-                  
-                  transformer.setXPathContext(xctxtOriginal);
-                
-                  // return from this xsl:iterate instruction's evaluation
-                  return;                  
+               if ((xslOnCompletionTemplate != null) && \
!transformer.isXslIterateBreakEvaluated()) { +                  \
transformer.setXslIterateOnCompletionActive(true); +                  \
xctxt.setSAXLocator(xslOnCompletionTemplate); +                  \
transformer.setCurrentElement(xslOnCompletionTemplate); +                  \
xslOnCompletionTemplate.execute(transformer); +                  \
transformer.setXslIterateOnCompletionActive(false);  }
+
+               transformer.setXslIterateBreakEvaluated(false);
            }
-           
-           // Evaluate xsl:iterate instruction, when value of its "select" attribute \
                evaluates 
-           // to a node set. 
-           DTMIterator sourceNodes = m_selectExpression.asIterator(xctxt, \
sourceNode); +           else {
+               // Evaluate xsl:iterate instruction, when value of its "select" \
attribute evaluates  +               // to a node set. 
+               DTMIterator sourceNodes = m_selectExpression.asIterator(xctxt, \
sourceNode);  
-           try {               
-               xctxt.pushCurrentNode(DTM.NULL);
-
-               IntStack currentNodes = xctxt.getCurrentNodeStack();
-
-               xctxt.pushCurrentExpressionNode(DTM.NULL);
-
-               IntStack currentExpressionNodes = \
                xctxt.getCurrentExpressionNodeStack();
-
-               xctxt.pushSAXLocatorNull();
-               xctxt.pushContextNodeList(sourceNodes);
-               transformer.pushElemTemplateElement(null);                            \
 +               try {               
+                   xctxt.pushCurrentNode(DTM.NULL);
+                   IntStack currentNodes = xctxt.getCurrentNodeStack();
+                   xctxt.pushCurrentExpressionNode(DTM.NULL);
+                   IntStack currentExpressionNodes = \
xctxt.getCurrentExpressionNodeStack(); +                   \
xctxt.pushSAXLocatorNull(); +                   \
xctxt.pushContextNodeList(sourceNodes); +                   \
transformer.pushElemTemplateElement(null);                                
-               int nextNode;
+                   int nextNode;
                
-               ElemIterateOnCompletion xslOnCompletionTemplate = null;
+                   ElemIterateOnCompletion xslOnCompletionTemplate = null;
                
-               while ((nextNode = sourceNodes.nextNode()) != DTM.NULL) {
-                   currentNodes.setTop(nextNode);
-                   currentExpressionNodes.setTop(nextNode);
+                   int idx = -1;
+                   while ((nextNode = sourceNodes.nextNode()) != DTM.NULL) {
+                      idx++;
+                      currentNodes.setTop(nextNode);
+                      currentExpressionNodes.setTop(nextNode);
                                                                         
-                   for (ElemTemplateElement elemTemplate = this.m_firstChild; \
elemTemplate != null;  +                      for (ElemTemplateElement elemTemplate = \
                this.m_firstChild; elemTemplate != null; 
                                                                           \
                elemTemplate = elemTemplate.m_nextSibling) {
-                       if ((elemTemplate instanceof ElemIterateOnCompletion) && 
+                          if ((elemTemplate instanceof ElemIterateOnCompletion) && 
                                                                         \
                (xslOnCompletionTemplate == null)) {
-                           xslOnCompletionTemplate = \
                (ElemIterateOnCompletion)elemTemplate;     
-                       }
+                              xslOnCompletionTemplate = \
(ElemIterateOnCompletion)elemTemplate;      +                          }
                        
-                       if \
                (!(XslTransformSharedDatastore.isXslIterateBreakEvaluated).booleanValue()) \
                {
-                           xctxt.setSAXLocator(elemTemplate);
-                           transformer.setCurrentElement(elemTemplate);
-                           elemTemplate.execute(transformer);
-                       }
-                       else {
-                           break;    
-                       }                                              
-                   }                                      
+                          if ((idx == 0) && (elemTemplate instanceof ElemParam)) {
+                              xctxt.setSAXLocator(elemTemplate);
+                              transformer.setCurrentElement(elemTemplate);
+                              \
((ElemParam)elemTemplate).setXslIterateIterationIdx(idx); +                           \
elemTemplate.execute(transformer);  +                          }
+                          else {
+                              if (!transformer.isXslIterateBreakEvaluated()) {
+                                  xctxt.setSAXLocator(elemTemplate);
+                                  transformer.setCurrentElement(elemTemplate);
+                                  elemTemplate.execute(transformer);
+                              }
+                              else {
+                                  break;    
+                              }
+                          }
+                      }                                      
                    
-                   if \
((XslTransformSharedDatastore.isXslIterateBreakEvaluated).booleanValue()) {           \
                
-                       break;   
+                      if (transformer.isXslIterateBreakEvaluated()) {
+                          break;   
+                      }
                    }
-               }
                
-               if ((xslOnCompletionTemplate != null) && \
                !(XslTransformSharedDatastore.
-                                                                                \
                isXslIterateBreakEvaluated).booleanValue()) {
-                    XslTransformSharedDatastore.isXslIterateOnCompletionActive = \
                Boolean.TRUE;
-                    xctxt.setSAXLocator(xslOnCompletionTemplate);
-                    transformer.setCurrentElement(xslOnCompletionTemplate);
-                    xslOnCompletionTemplate.execute(transformer);
-                    XslTransformSharedDatastore.isXslIterateOnCompletionActive = \
                Boolean.FALSE;
-               }
+                  if ((xslOnCompletionTemplate != null) && \
!transformer.isXslIterateBreakEvaluated()) { +                       \
transformer.setXslIterateOnCompletionActive(true); +                       \
xctxt.setSAXLocator(xslOnCompletionTemplate); +                       \
transformer.setCurrentElement(xslOnCompletionTemplate); +                       \
xslOnCompletionTemplate.execute(transformer); +                       \
transformer.setXslIterateOnCompletionActive(false); +                  }
                
-               XslTransformSharedDatastore.isXslIterateBreakEvaluated = \
                Boolean.FALSE; 
-           }
-           finally {
-              xctxt.popSAXLocator();
-              xctxt.popContextNodeList();
-              transformer.popElemTemplateElement();
-              xctxt.popCurrentExpressionNode();
-              xctxt.popCurrentNode();
-              sourceNodes.detach();
-           }
-        
-           // Restore the xpath context, to where it was before this xsl:iterate 
-           // instruction began an evaluation.
-           transformer.setXPathContext(xctxtOriginal);        
+                  transformer.setXslIterateBreakEvaluated(false);
+             }
+             finally {
+                 xctxt.popSAXLocator();
+                 xctxt.popContextNodeList();
+                 transformer.popElemTemplateElement();
+                 xctxt.popCurrentExpressionNode();
+                 xctxt.popCurrentNode();
+                 sourceNodes.detach();
+             }
+          }       
       }
       
       /**
diff --git a/src/org/apache/xalan/templates/ElemIterateBreak.java \
b/src/org/apache/xalan/templates/ElemIterateBreak.java index c2df8afc..e8eee619 \
                100644
--- a/src/org/apache/xalan/templates/ElemIterateBreak.java
+++ b/src/org/apache/xalan/templates/ElemIterateBreak.java
@@ -20,7 +20,6 @@ package org.apache.xalan.templates;
 import javax.xml.transform.TransformerException;
 
 import org.apache.xalan.transformer.TransformerImpl;
-import org.apache.xalan.xslt.util.XslTransformSharedDatastore;
 import org.apache.xml.serializer.SerializationHandler;
 import org.apache.xpath.Expression;
 import org.apache.xpath.ExpressionOwner;
@@ -28,21 +27,14 @@ import org.apache.xpath.XPath;
 import org.apache.xpath.XPathContext;
 import org.xml.sax.SAXException;
 
-/**
- * XSLT 3.0 xsl:break element.
- * 
-   <xsl:break select? = expression>
-      <!-- Content: sequence-constructor -->
-   </xsl:break>
-         
-   @author Mukul Gandhi <mukulg@apache.org>
- * 
- * @xsl.usage advanced
- */
 /*
  * Implementation of the XSLT 3.0 xsl:break instruction.
  * 
- * The XSLT xsl:break element is intended to be used, within xsl:iterate element.
+ * Ref : https://www.w3.org/TR/xslt-30/#element-iterate
+ * 
+ * @author Mukul Gandhi <mukulg@apache.org>
+ * 
+ * @xsl.usage advanced
  */
 public class ElemIterateBreak extends ElemTemplateElement implements ExpressionOwner
 {
@@ -169,7 +161,7 @@ public class ElemIterateBreak extends ElemTemplateElement \
implements ExpressionO  
             if (isXslBreakDescendantOfXslIterate && \
isXslInstructionInTailPositionOfSequenceConstructor(this)) {                \
                transformXslBreakInstruction(transformer);
-                XslTransformSharedDatastore.isXslIterateBreakEvaluated = \
Boolean.TRUE; +                transformer.setXslIterateBreakEvaluated(true);
             }
             else {
                 throw new TransformerException("XTSE3120 : an xsl:break instruction \
                is not in a "
diff --git a/src/org/apache/xalan/templates/ElemIterateNextIteration.java \
b/src/org/apache/xalan/templates/ElemIterateNextIteration.java index \
                3ceaa4ad..23a35516 100644
--- a/src/org/apache/xalan/templates/ElemIterateNextIteration.java
+++ b/src/org/apache/xalan/templates/ElemIterateNextIteration.java
@@ -33,31 +33,20 @@ import org.apache.xpath.objects.XObject;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
-/**
- * XSLT 3.0 xsl:next-iteration element.
- *    
-   <xsl:next-iteration>
-      <!-- Content: (xsl:with-param*) -->
-   </xsl:next-iteration>
-         
-   @author Mukul Gandhi <mukulg@apache.org>
- * 
- * @xsl.usage advanced
- */
 /*
  * Implementation of the XSLT 3.0 xsl:next-iteration instruction.
  * 
- * The XSLT xsl:next-iteration element is intended to be used, within 
- * xsl:iterate element.
+ * Ref : https://www.w3.org/TR/xslt-30/#element-iterate
+ * 
+ * @author Mukul Gandhi <mukulg@apache.org>
+ * 
+ * @xsl.usage advanced
  */
 public class ElemIterateNextIteration extends ElemTemplateElement implements \
ExpressionOwner  {
     
      private static final long serialVersionUID = -582877657433106548L;
      
-     // revisit.
-     // can we have better way to maintain xsl:next-iteration->xsl:with-param* \
                state, instead of having this with
-     // 'public static' visibility.
      public static List<XslIterateParamWithparamData> fWithparamList = new \
ArrayList<XslIterateParamWithparamData>();  
      /**
@@ -164,25 +153,20 @@ public class ElemIterateNextIteration extends \
ElemTemplateElement implements Exp  {
            
             XPathContext xpathContext = transformer.getXPathContext();
-  
-            boolean isXslNextIterationDescendantOfXslIterate = false;
             
-            if (isXslNextIterationDescendantOfXslIterate(this)) {
-                isXslNextIterationDescendantOfXslIterate = true;       
-            }
-            else {
-                throw new TransformerException("XTSE3120 : an xsl:next-iteration \
                instruction doesn't "
-                                                                + "have xsl:iterate \
                instruction as ancestor.", 
-                                                                                     \
xpathContext.getSAXLocator());   +            if \
(!isXslNextIterationDescendantOfXslIterate(this)) { +                throw new \
TransformerException("XTSE3120 : An xsl:next-iteration instruction doesn't " +        \
+ "have xsl:iterate instruction as an ancestor.",  +                                  \
xpathContext.getSAXLocator());   }
             
-            if (isXslNextIterationDescendantOfXslIterate && \
isXslInstructionInTailPositionOfSequenceConstructor(this)) { +            if \
(isXslInstructionInTailPositionOfSequenceConstructor(this)) {  \
elemIterateNextIterationProcessing(transformer);  }
             else {
                 throw new TransformerException("XTSE3120 : an xsl:next-iteration \
                instruction is not in a "
-                                                                + "tail position \
                within the sequence constructor of currently "
-                                                                + "active \
xsl:iterate instruction.", xpathContext.getSAXLocator());    +                        \
+ "tail position within the sequence constructor of currently " +                     \
+ "active xsl:iterate instruction.", xpathContext.getSAXLocator());     }
        }
        
@@ -193,14 +177,14 @@ public class ElemIterateNextIteration extends \
                ElemTemplateElement implements Exp
         * 
         * @xsl.usage advanced
         */
-        public void elemIterateNextIterationProcessing(TransformerImpl transformer) \
                throws 
-                                                                               \
TransformerException { +        private void \
elemIterateNextIterationProcessing(TransformerImpl transformer) throws  +             \
TransformerException {  
             XPathContext xctxt = transformer.getXPathContext();
             
             int contextNode = xctxt.getContextNode();
             
-            // clear the, xsl:next-iteration->xsl:with-param* list storage before
+            // Clear the, xsl:next-iteration->xsl:with-param* list storage before
             // evaluating this xsl:next-iteration element.
             fWithparamList.clear();
             
@@ -227,7 +211,7 @@ public class ElemIterateNextIteration extends ElemTemplateElement \
implements Exp  
             if ((ElemIterate.fXslIterateParamWithparamDataList).size() != \
                fWithparamList.size()) {
                 throw new TransformerException("XTSE0580 : within xsl:iterate, the \
                number of xsl:param elements are not equal to "
-                                                               + "number of \
xsl:next-iteration's xsl:with-param elements.", xctxt.getSAXLocator());      +        \
+ "number of xsl:next-iteration's xsl:with-param elements.", xctxt.getSAXLocator());  \
  }
             else {
                for (int idx = 0; idx < \
(ElemIterate.fXslIterateParamWithparamDataList).size(); idx ++) { @@ -235,23 +219,100 \
                @@ public class ElemIterateNextIteration extends ElemTemplateElement \
                implements Exp
                    XslIterateParamWithparamData withParamData = \
                fWithparamList.get(idx);
                    if (!(paramData.getNameVal()).equals(withParamData.getNameVal())) \
                {
                        throw new TransformerException("XTSE3130 : within \
                xsl:iterate, xsl:param and xsl:with-param names at position " + 
-                                                                                     \
(idx + 1) + " are not same.", xctxt.getSAXLocator());         +                       \
(idx + 1) + " are not same.", xctxt.getSAXLocator());          }
                }
             }
             
+            // Update all of xsl:iterate's xsl:param values, using the corresponding
+            // xsl:next-iteration's xsl:with-param values. The code within 'for' \
loop below, +            // updates each of the xsl:iterate->xsl:param's values for \
xsl:iterate's second and  +            // greater iterations. For xsl:iterate's first \
iteration, xsl:param's get their +            // values from the xsl:param \
instructions themselves.  VariableStack varStack = xctxt.getVarStack();
             for (int idx = 0; idx < fWithparamList.size(); idx++) {
                 XslIterateParamWithparamData withParamData = \
fWithparamList.get(idx); +                                                
+                QName xslParamQName = withParamData.getNameVal();                
+                ElemParam elemParam = getElemParamForQName(xslParamQName);
                 XPath withParamSelectVal = withParamData.getSelectVal();             \
                
-                XObject evalResult = withParamSelectVal.execute(xctxt, contextNode, \
                this);
-                // update value of current xsl:next-iteration's current xsl:param 
-                // 'parameter'. when xsl:iterate's new iteration is entered, this
-                // parameter shall have this new value.
-                varStack.setLocalVariable(idx, evalResult);
+                XObject withParamVal = withParamSelectVal.execute(xctxt, \
contextNode, this); +                varStack.setLocalVariable(elemParam.getIndex(), \
withParamVal);  }
         }
         
+        /*
+         * For the currently active xsl:next-iteration instruction, find reference \
to +         * its xsl:iterate->xsl:param element for a given \
xsl:iterate->xsl:param's name. +         * 
+         * We find this xsl:param element reference, by xsl element traversal on
+         * preceding-sibling and ancestor axes directions starting from the current
+         * xsl:next-iteration instruction.
+         * 
+         * This method shall always find, an eligible non-null \
xsl:iterate->xsl:param  +         * element reference for a given \
xsl:iterate->xsl:param's name. +         */
+        private ElemParam getElemParamForQName(QName xslParamQName) {
+           ElemParam elemParam = null;
+           
+           // First, we search for the desired xsl:param element on the \
preceding-sibling  +           // axis direction.
+           ElemTemplateElement prevSibling = \
(ElemTemplateElement)getPreviousSibling(); +           while (prevSibling != null) {
+              if (prevSibling instanceof ElemParam) {
+                 ElemParam elemParamTemp = (ElemParam)prevSibling;
+                 if ((elemParamTemp.getName()).equals(xslParamQName)) {
+                    elemParam = elemParamTemp;
+                    break; 
+                 }
+                 else {
+                    prevSibling = \
(ElemTemplateElement)(prevSibling.getPreviousSibling());  +                 }
+              }
+              else {
+                 prevSibling = \
(ElemTemplateElement)(prevSibling.getPreviousSibling());  +              }
+           }
+           
+           // The desired xsl:param element was not found, on the preceding-sibling \
axis +           // direction. Now, we attempt a new search for desired xsl:param \
element  +           // on the ancestor axis direction. 
+           if (elemParam == null) {
+              ElemTemplateElement parentElem = getParentElem();
+              while (parentElem != null) {
+                 if (parentElem instanceof ElemIterate) {
+                    ElemTemplateElement elemIterateChild = \
(ElemTemplateElement)(parentElem.getFirstChild()); +                    boolean \
isToBreakFromCheck = false; +                    while (elemIterateChild != null) {
+                        if (elemIterateChild instanceof ElemParam) {
+                           ElemParam elemParamTemp = (ElemParam)elemIterateChild;
+                           if ((elemParamTemp.getName()).equals(xslParamQName)) {
+                               elemParam = elemParamTemp;
+                               isToBreakFromCheck = true;
+                               break;
+                           }
+                           else {
+                              elemIterateChild = \
elemIterateChild.getNextSiblingElem(); +                           }
+                        }
+                        else {
+                           elemIterateChild = elemIterateChild.getNextSiblingElem(); \
 +                        }
+                    }
+                    
+                    if (isToBreakFromCheck) {
+                       break; 
+                    }
+                 }
+                 else {
+                    parentElem = parentElem.getParentElem();
+                 }
+              }
+           }
+           
+           return elemParam;
+        }
+        
         /*
          * Determine whether, an xsl:next-iteration instruction has xsl:iterate \
                instruction 
          * as ancestor. 
diff --git a/src/org/apache/xalan/templates/ElemIterateOnCompletion.java \
b/src/org/apache/xalan/templates/ElemIterateOnCompletion.java index \
                1e51ed95..781d7bf0 100644
--- a/src/org/apache/xalan/templates/ElemIterateOnCompletion.java
+++ b/src/org/apache/xalan/templates/ElemIterateOnCompletion.java
@@ -20,7 +20,6 @@ package org.apache.xalan.templates;
 import javax.xml.transform.TransformerException;
 
 import org.apache.xalan.transformer.TransformerImpl;
-import org.apache.xalan.xslt.util.XslTransformSharedDatastore;
 import org.apache.xml.serializer.SerializationHandler;
 import org.apache.xpath.Expression;
 import org.apache.xpath.ExpressionOwner;
@@ -30,22 +29,14 @@ import org.xml.sax.SAXException;
 
 import com.sun.org.apache.xml.internal.dtm.DTM;
 
-/**
- * XSLT 3.0 xsl:on-completion element.
- * 
-   <xsl:on-completion select? = expression>
-      <!-- Content: sequence-constructor -->
-   </xsl:on-completion>
-         
-   @author Mukul Gandhi <mukulg@apache.org>
- * 
- * @xsl.usage advanced
- */
 /*
  * Implementation of the XSLT 3.0 xsl:on-completion instruction.
  * 
- * The XSLT xsl:on-completion element is intended to be used, within 
- * xsl:iterate element.
+ * Ref : https://www.w3.org/TR/xslt-30/#element-iterate
+ * 
+ * @author Mukul Gandhi <mukulg@apache.org>
+ * 
+ * @xsl.usage advanced
  */
 public class ElemIterateOnCompletion extends ElemTemplateElement implements \
ExpressionOwner  {
@@ -167,16 +158,15 @@ public class ElemIterateOnCompletion extends \
                ElemTemplateElement implements Expr
        * 
        * @xsl.usage advanced
        */
-       public void transformXslOncompletionInstruction(TransformerImpl transformer) \
                throws 
-                                                                               \
TransformerException { +       private void \
transformXslOncompletionInstruction(TransformerImpl transformer)  +                   \
throws TransformerException {  
-           if ((XslTransformSharedDatastore.isXslIterateOnCompletionActive).booleanValue()) \
                {
-               final XPathContext originalXctxt = transformer.getXPathContext();
-               
+           if (transformer.isXslIterateOnCompletionActive()) {               
                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.
+               // During evaluation of xsl:on-completion instruction, the XPath \
context item +               // is absent. We make following two changes to an active \
XPath context to +               // ensure this.
                xctxt.pushCurrentNode(DTM.NULL);
                xctxt.pushCurrentExpressionNode(DTM.NULL);
                
@@ -185,9 +175,11 @@ public class ElemIterateOnCompletion extends ElemTemplateElement \
implements Expr  
                    try {
                        m_selectExpression.executeCharsToContentHandler(xctxt, rth);
-                   } catch (TransformerException ex) {
+                   } 
+                   catch (TransformerException ex) {
                        throw ex;
-                   } catch (SAXException ex) {
+                   } 
+                   catch (SAXException ex) {
                        throw new TransformerException(ex);
                    }
                }
@@ -199,9 +191,6 @@ public class ElemIterateOnCompletion extends ElemTemplateElement \
implements Expr  elemTemplate.execute(transformer);
                    } 
                }
-               
-               // restore the XPath original context, on current XSLT transformer \
                object
-               transformer.setXPathContext(originalXctxt);
            }                      
        }
       
diff --git a/src/org/apache/xalan/templates/ElemParam.java \
b/src/org/apache/xalan/templates/ElemParam.java index bf4033ca..d9273360 100644
--- a/src/org/apache/xalan/templates/ElemParam.java
+++ b/src/org/apache/xalan/templates/ElemParam.java
@@ -42,9 +42,15 @@ public class ElemParam extends ElemVariable
   static final long serialVersionUID = -1131781475589006431L;
   
   int m_qnameID;
+  
+  /**
+   * This class field, supports evaluation of stylesheet 
+   * xsl:iterate->xsl:param elements.
+   */
+  private int xslIterateIterationIdx = -1;
 
   /**
-   * Constructor ElemParam
+   * Constructor ElemParam.
    *
    */
   public ElemParam(){}
@@ -117,27 +123,27 @@ public class ElemParam extends ElemVariable
     
     SourceLocator srcLocator = xctx.getSAXLocator();
     
-    String asAttrVal = getAs();
+    boolean isChildElemOfXslElemIterate = false;
+    if (getParentElem() instanceof ElemIterate) {
+       isChildElemOfXslElemIterate = true; 
+    }
     
-    if(!vars.isLocalSet(m_index)) {
-        // The caller of this stylesheet callable component, didn't provide the 
-        // parameter value via xsl:with-param instruction.
-        
-        // We'll determine the parameter's value by evaluating either the \
                parameter's
-        // 'select' attribute, or the contained sequence constructor within \
                xsl:param 
-        // element.
+    if (!vars.isLocalSet(m_index) || (isChildElemOfXslElemIterate && \
(xslIterateIterationIdx == 0))) { +        // The caller of an stylesheet callable \
component (associated with this xsl:param element),  +        // didn't provide \
xsl:param's value via xsl:with-param instruction.  
         int sourceNode = transformer.getXPathContext().getCurrentNode();
         
         try {
            XObject var = getValue(transformer, sourceNode);
-           if (var == null) {
+           if (var != null) {
+              transformer.getXPathContext().getVarStack().setLocalVariable(m_index, \
var);     +           }
+           else {              
               throw new TransformerException("XTTE0590 : The value to parameter " + \
                m_qname.toString() + " cannot be assigned. "
                                                                              + \
                "Either an input content for parameter is not available within "
-                                                                             + \
"stylesheet context, or parameter's value cannot be cast to an expected type.", \
srcLocator);   +                                                                      \
+ "stylesheet context, or parameter's value cannot be cast to an expected type.", \
srcLocator);  }
-           
-           transformer.getXPathContext().getVarStack().setLocalVariable(m_index, \
var);  }
         catch (TransformerException ex) {
             throw new TransformerException("XTTE0590 : The value to parameter " + \
m_qname.toString() + " cannot be assigned. " @@ -146,12 +152,13 @@ public class \
ElemParam extends ElemVariable  }
     }
     else {
-        // The caller of this stylesheet callable component, has provided the 
-        // parameter's value via xsl:with-param instruction.
+        // The caller of an stylesheet callable component (associated with this \
xsl:param element),  +        // has provided xsl:param's value via xsl:with-param \
instruction.  
-        // If the xsl:param instruction has 'as' attribute, we'll check below
-        // whether the parameter's value conforms to the sequence type specified by
+        // If the xsl:param instruction has an 'as' attribute, we check below
+        // whether xsl:param's value conforms to the sequence type specified by
         // xsl:param's 'as' attribute.
+        String asAttrVal = getAs();
         
         if (asAttrVal != null) {
           try {
@@ -172,9 +179,15 @@ public class ElemParam extends ElemVariable
        }
     }
     
+    // Reset this class field
+    xslIterateIterationIdx = -1;
     
     if (transformer.getDebug())
       transformer.getTraceManager().fireTraceEndEvent(this);
   }
   
+  public void setXslIterateIterationIdx(int iterationIdx) {
+     xslIterateIterationIdx = iterationIdx;   
+  }
+  
 }
diff --git a/src/org/apache/xalan/transformer/TransformerImpl.java \
b/src/org/apache/xalan/transformer/TransformerImpl.java index 7c35fdd8..75e585a8 \
                100644
--- a/src/org/apache/xalan/transformer/TransformerImpl.java
+++ b/src/org/apache/xalan/transformer/TransformerImpl.java
@@ -363,6 +363,16 @@ public class TransformerImpl extends Transformer
 
   /** NEEDSDOC Field m_shouldReset          */
   private boolean m_shouldReset = true;
+  
+  /**
+   * A class field, to support xsl:iterate instruction evaluation.
+   */
+  private boolean isXslIterateBreakEvaluated = false;
+  
+  /**
+   * A class field, to support xsl:iterate instruction evaluation.
+   */
+  private boolean isXslIterateOnCompletionActive = false;
 
   /**
    * NEEDSDOC Method setShouldReset 
@@ -3789,5 +3799,21 @@ public class TransformerImpl extends Transformer
         return m_source_location;
     }
 
+    public boolean isXslIterateBreakEvaluated() {
+        return isXslIterateBreakEvaluated;
+    }
+
+    public void setXslIterateBreakEvaluated(boolean isXslIterateBreakEvaluated) {
+        this.isXslIterateBreakEvaluated = isXslIterateBreakEvaluated;
+    }
+
+    public boolean isXslIterateOnCompletionActive() {
+        return isXslIterateOnCompletionActive;
+    }
+
+    public void setXslIterateOnCompletionActive(boolean \
isXslIterateOnCompletionActive) { +        this.isXslIterateOnCompletionActive = \
isXslIterateOnCompletionActive; +    }
+
 }  // end TransformerImpl class
 
diff --git a/src/org/apache/xalan/xslt/util/XslTransformSharedDatastore.java \
b/src/org/apache/xalan/xslt/util/XslTransformSharedDatastore.java index \
                c6c67fac..5ac34555 100644
--- a/src/org/apache/xalan/xslt/util/XslTransformSharedDatastore.java
+++ b/src/org/apache/xalan/xslt/util/XslTransformSharedDatastore.java
@@ -27,11 +27,5 @@ public class XslTransformSharedDatastore {
     
     // XSLT document's uri, used for error reporting
     public static String xslSystemId;
-    
-    // To support xsl:iterate instruction evaluation
-    public static Boolean isXslIterateBreakEvaluated = Boolean.FALSE;
-    
-    // To support xsl:iterate instruction evaluation
-    public static Boolean isXslIterateOnCompletionActive = Boolean.FALSE;
 
 }
diff --git a/tests/org/apache/xalan/xslt3/XslIterateTests.java \
b/tests/org/apache/xalan/xslt3/XslIterateTests.java index 761bba01..61faffdc 100644
--- a/tests/org/apache/xalan/xslt3/XslIterateTests.java
+++ b/tests/org/apache/xalan/xslt3/XslIterateTests.java
@@ -290,5 +290,45 @@ public class XslIterateTests extends XslTransformTestsUtil {
         
         runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, \
null);  }
+    
+    @Test
+    public void xslIterateTest25() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test23.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test23.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test23.out";             \
 +        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, \
null); +    }
+    
+    @Test
+    public void xslIterateTest26() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test24.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test24.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test24.out";             \
 +        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, \
null); +    }
+    
+    @Test
+    public void xslIterateTest27() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test25.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test25.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test25.out";             \
 +        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, \
null); +    }
+    
+    @Test
+    public void xslIterateTest28() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_g.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test26.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test26.out";             \
 +        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, \
null); +    }
 
 }
diff --git a/tests/xsl_iterate/gold/test23.out b/tests/xsl_iterate/gold/test23.out
new file mode 100644
index 00000000..439348bf
--- /dev/null
+++ b/tests/xsl_iterate/gold/test23.out
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <factorial num="5">120</factorial>
+  <factorial num="6">720</factorial>
+</result>
diff --git a/tests/xsl_iterate/gold/test24.out b/tests/xsl_iterate/gold/test24.out
new file mode 100644
index 00000000..bed9f2e2
--- /dev/null
+++ b/tests/xsl_iterate/gold/test24.out
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <factorial num="1">1</factorial>
+  <factorial num="2">2</factorial>
+  <factorial num="3">6</factorial>
+  <factorial num="4">24</factorial>
+  <factorial num="5">120</factorial>
+  <factorial num="6">720</factorial>
+  <factorial num="7">5040</factorial>
+</result>
diff --git a/tests/xsl_iterate/gold/test25.out b/tests/xsl_iterate/gold/test25.out
new file mode 100644
index 00000000..439348bf
--- /dev/null
+++ b/tests/xsl_iterate/gold/test25.out
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <factorial num="5">120</factorial>
+  <factorial num="6">720</factorial>
+</result>
diff --git a/tests/xsl_iterate/gold/test26.out b/tests/xsl_iterate/gold/test26.out
new file mode 100644
index 00000000..bed9f2e2
--- /dev/null
+++ b/tests/xsl_iterate/gold/test26.out
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <factorial num="1">1</factorial>
+  <factorial num="2">2</factorial>
+  <factorial num="3">6</factorial>
+  <factorial num="4">24</factorial>
+  <factorial num="5">120</factorial>
+  <factorial num="6">720</factorial>
+  <factorial num="7">5040</factorial>
+</result>
diff --git a/tests/xsl_iterate/test1_g.xml b/tests/xsl_iterate/test1_g.xml
new file mode 100644
index 00000000..7931220e
--- /dev/null
+++ b/tests/xsl_iterate/test1_g.xml
@@ -0,0 +1,4 @@
+<info>
+  <from>1</from>
+  <to>7</to>
+</info>
\ No newline at end of file
diff --git a/tests/xsl_iterate/test23.xsl b/tests/xsl_iterate/test23.xsl
new file mode 100644
index 00000000..33414d0a
--- /dev/null
+++ b/tests/xsl_iterate/test23.xsl
@@ -0,0 +1,64 @@
+<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 xsl:iterate instruction. -->            \
 +                
+  <xsl:output method="xml" indent="yes"/>
+  
+  <xsl:template match="/">     
+     <result>
+        <!-- Evaluate factorial of a positive integer value. -->
+        <xsl:variable name="inpNum" select="5" as="xs:integer"/>        
+        <xsl:iterate select="2 to $inpNum">
+	       <xsl:param name="result" select="1" as="xs:integer"/>
+	       <xsl:on-completion>
+	          <factorial num="{$inpNum}">
+	   	         <xsl:value-of select="$result"/>
+     	      </factorial>
+	       </xsl:on-completion>
+	       <xsl:variable name="currVal" select="."/>
+	       <xsl:next-iteration>
+	          <xsl:with-param name="result" select="$result * $currVal" \
as="xs:integer"/> +	       </xsl:next-iteration>
+        </xsl:iterate>
+
+        <!-- Evaluate factorial of another positive integer value. -->
+        <xsl:variable name="inpNum" select="6" as="xs:integer"/>         
+	    <xsl:iterate select="2 to $inpNum">
+           <xsl:param name="result" select="1" as="xs:integer"/>
+	       <xsl:on-completion>
+              <factorial num="{$inpNum}">
+		         <xsl:value-of select="$result"/>
+	          </factorial>
+	       </xsl:on-completion>
+	       <xsl:variable name="currVal" select="."/>
+	       <xsl:next-iteration>
+	          <xsl:with-param name="result" select="$result * $currVal" \
as="xs:integer"/> +           </xsl:next-iteration>
+        </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>
\ No newline at end of file
diff --git a/tests/xsl_iterate/test24.xsl b/tests/xsl_iterate/test24.xsl
new file mode 100644
index 00000000..25a3f2f0
--- /dev/null
+++ b/tests/xsl_iterate/test24.xsl
@@ -0,0 +1,72 @@
+<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 xsl:iterate instruction. -->            \
 +                
+  <xsl:output method="xml" indent="yes"/>
+  
+  <xsl:template match="/">     
+     <result>
+        <!-- Evaluate factorial of various positive integer values,
+             provided by xsl:for-each instruction.
+        -->
+        <xsl:for-each select="1 to 7">
+          <xsl:variable name="num" select="." as="xs:integer"/>
+          <xsl:copy-of select="fn0:factorial($num)"/>
+        </xsl:for-each>
+     </result>
+  </xsl:template>
+  
+  <!-- A stylesheet function, to evaluate factorial of a positive 
+       integer value. 
+  -->
+  <xsl:function name="fn0:factorial" as="element(factorial)">
+     <xsl:param name="inpNum" as="xs:integer"/>
+
+     <xsl:choose>
+        <xsl:when test="$inpNum = 1">
+          <factorial num="{$inpNum}">
+	         <xsl:value-of select="1"/>
+     	  </factorial>
+        </xsl:when>
+        <xsl:otherwise>
+           <xsl:iterate select="2 to $inpNum">
+              <xsl:param name="result" select="1" as="xs:integer"/>
+              <xsl:on-completion>
+	             <factorial num="{$inpNum}">
+	                <xsl:value-of select="$result"/>
+	     	     </factorial>
+	          </xsl:on-completion>
+              <xsl:variable name="currVal" select="."/>
+              <xsl:next-iteration>
+     	         <xsl:with-param name="result" select="$result * $currVal" \
as="xs:integer"/> +              </xsl:next-iteration>
+           </xsl:iterate>
+        </xsl:otherwise>
+     </xsl:choose>
+  </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/xsl_iterate/test25.xsl b/tests/xsl_iterate/test25.xsl
new file mode 100644
index 00000000..b29c3b9f
--- /dev/null
+++ b/tests/xsl_iterate/test25.xsl
@@ -0,0 +1,69 @@
+<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 xsl:iterate instruction. -->            \
 +                
+  <xsl:output method="xml" indent="yes"/>
+  
+  <xsl:template match="/">     
+     <result>
+        <!-- Evaluate factorial of a positive integer value, by invoking a 
+             stylesheet named template. 
+        -->
+        <xsl:variable name="inpNum" select="5" as="xs:integer"/>
+        <xsl:call-template name="factorial">
+           <xsl:with-param name="inpNum" select="$inpNum" as="xs:integer"/>
+        </xsl:call-template>
+        
+        <!-- Evaluate factorial of another positive integer value, by invoking a 
+             stylesheet named template. 
+        -->
+	    <xsl:variable name="inpNum" select="6" as="xs:integer"/>
+	    <xsl:call-template name="factorial">
+	       <xsl:with-param name="inpNum" select="$inpNum" as="xs:integer"/>
+        </xsl:call-template>
+     </result>
+  </xsl:template>
+  
+  <!-- A stylesheet named template, to evaluate factorial of a positive 
+       integer value. 
+  -->
+  <xsl:template name="factorial" as="element(factorial)">
+     <xsl:param name="inpNum" as="xs:integer"/>
+     <xsl:iterate select="2 to $inpNum">
+       <xsl:param name="result" select="1" as="xs:integer"/>       
+       <xsl:on-completion>
+       	  <factorial num="{$inpNum}">
+       	     <xsl:value-of select="$result"/>
+       	  </factorial>
+       </xsl:on-completion>
+       <xsl:variable name="currVal" select="."/>
+       <xsl:next-iteration>
+  	      <xsl:with-param name="result" select="$result * $currVal" as="xs:integer"/>
+       </xsl:next-iteration>
+     </xsl:iterate>
+  </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_iterate/test26.xsl b/tests/xsl_iterate/test26.xsl
new file mode 100644
index 00000000..ca721a8d
--- /dev/null
+++ b/tests/xsl_iterate/test26.xsl
@@ -0,0 +1,75 @@
+<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_g.xml -->
+  
+  <!-- An XSLT stylesheet test case, to test xsl:iterate instruction. -->            \
 +                
+  <xsl:output method="xml" indent="yes"/>
+  
+  <xsl:template match="/info">     
+     <result>
+        <!-- Evaluate factorial of various positive integer values,
+             provided by xsl:for-each instruction.
+        -->
+        <xsl:for-each select="xs:integer(from) to xs:integer(to)">
+           <xsl:variable name="inpNum" select="."/>
+           <xsl:call-template name="factorial">
+              <xsl:with-param name="inpNum" select="$inpNum" as="xs:integer"/>
+           </xsl:call-template>
+	    </xsl:for-each>
+     </result>
+  </xsl:template>
+  
+  <!-- A stylesheet named template, to evaluate factorial of a positive 
+       integer value. 
+  -->
+  <xsl:template name="factorial" as="element(factorial)">
+     <xsl:param name="inpNum" as="xs:integer"/>
+     
+     <xsl:choose>
+        <xsl:when test="$inpNum = 1">
+           <factorial num="{$inpNum}">
+     	      <xsl:value-of select="1"/>
+           </factorial>
+        </xsl:when>
+        <xsl:otherwise>
+           <xsl:iterate select="2 to $inpNum">
+              <xsl:param name="result" select="1" as="xs:integer"/>              
+              <xsl:on-completion>
+	             <factorial num="{$inpNum}">
+	                <xsl:value-of select="$result"/>
+	             </factorial>
+              </xsl:on-completion>
+              <xsl:variable name="currVal" select="."/>
+              <xsl:next-iteration>
+          	      <xsl:with-param name="result" select="$result * $currVal"/>
+              </xsl:next-iteration>
+           </xsl:iterate>
+        </xsl:otherwise>
+     </xsl:choose>
+  </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


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


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic