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/13 13:57:23 UTC

[xalan-java] branch xalan-j_xslt3.0 updated: implementing xsl:iterate's xsl:param and xsl:with-param elements. committing few related new xslt 3.0 test cases as well. with this commit, xalanj's dev branch xalan-j_xslt3.0 has majority of xsl:iterate's implementation complete.

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 46f24c4e implementing xsl:iterate's xsl:param and xsl:with-param elements. committing few related new xslt 3.0 test cases as well. with this commit, xalanj's dev branch xalan-j_xslt3.0 has majority of xsl:iterate's implementation complete.
46f24c4e is described below

commit 46f24c4ee997f2dae6a41ea5e95dfddc7ff513b9
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Tue Jun 13 19:27:04 2023 +0530

    implementing xsl:iterate's xsl:param and xsl:with-param elements. committing few related new xslt 3.0 test cases as well. with this commit, xalanj's dev branch xalan-j_xslt3.0 has majority of xsl:iterate's implementation complete.
---
 src/org/apache/xalan/processor/XSLTSchema.java    |   5 +-
 src/org/apache/xalan/templates/ElemIterate.java   | 179 +++++++++++++++++++---
 tests/org/apache/xalan/xslt3/XslIterateTests.java |  40 +++++
 tests/xsl_iterate/gold/iterate-002.out            |  20 +++
 tests/xsl_iterate/gold/iterate-003.out            |  11 ++
 tests/xsl_iterate/gold/test10.out                 |   1 +
 tests/xsl_iterate/gold/test9.out                  |   1 +
 tests/xsl_iterate/iterate-002.xsl                 |  47 ++++++
 tests/xsl_iterate/iterate-003.xsl                 |  56 +++++++
 tests/xsl_iterate/iterate001.xml                  |  89 +++++++++++
 tests/xsl_iterate/test10.xsl                      |  54 +++++++
 tests/xsl_iterate/test9.xsl                       |  51 ++++++
 12 files changed, 532 insertions(+), 22 deletions(-)

diff --git a/src/org/apache/xalan/processor/XSLTSchema.java b/src/org/apache/xalan/processor/XSLTSchema.java
index 37d76749..d0aeb9cf 100644
--- a/src/org/apache/xalan/processor/XSLTSchema.java
+++ b/src/org/apache/xalan/processor/XSLTSchema.java
@@ -521,7 +521,7 @@ public class XSLTSchema extends XSLTElementDef
                                                 ElemNonMatchingSubstring.class /* class object */, true, false, true, 20, true);
     
     XSLTElementDef xslIterate = new XSLTElementDef(this, Constants.S_XSLNAMESPACEURL, "iterate",
-                                                   null /*alias */, templateElements,
+                                                   null /*alias */, templateElementsAndParams,
                                                    new XSLTAttributeDef[]{ selectAttrRequired }, new ProcessorTemplateElem(),
                                                    ElemIterate.class /* class object */, true, false, true, 20, true);
     
@@ -532,7 +532,8 @@ public class XSLTSchema extends XSLTElementDef
                                                                true, 20, true);
     
     XSLTElementDef xslIterateNextIteration = new XSLTElementDef(this, Constants.S_XSLNAMESPACEURL, "next-iteration",
-                                                                null /*alias */, templateElements,
+                                                                null /*alias */, 
+                                                                new XSLTElementDef[]{ xslWithParam },
                                                                 new XSLTAttributeDef[] { }, new ProcessorTemplateElem(),
                                                                 ElemIterateNextIteration.class /* class object */, true, false, 
                                                                 true, 20, true);
diff --git a/src/org/apache/xalan/templates/ElemIterate.java b/src/org/apache/xalan/templates/ElemIterate.java
index 572c1e6d..286d208b 100644
--- a/src/org/apache/xalan/templates/ElemIterate.java
+++ b/src/org/apache/xalan/templates/ElemIterate.java
@@ -28,10 +28,15 @@ import org.apache.xml.dtm.DTM;
 import org.apache.xml.dtm.DTMIterator;
 import org.apache.xml.dtm.DTMManager;
 import org.apache.xml.utils.IntStack;
+import org.apache.xml.utils.QName;
 import org.apache.xpath.Expression;
 import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.VariableStack;
 import org.apache.xpath.XPath;
 import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
 
 /**
  * XSLT 3.0 xsl:iterate element.
@@ -58,6 +63,28 @@ import org.apache.xpath.XPathContext;
  */
 /*
  * Implementation of the XSLT 3.0 xsl:iterate instruction.
+ * 
+ * An xsl:iterate instruction, functions like a loop, with following main features,
+ * 1) To be able to process a sequence of items in order, similar to how xsl:for-each 
+ *    instruction shall do such processing.
+ * 2) An xsl:iterate instruction has ability to exit from the loop prior to the 
+ *    exhaustion of the input sequence when particular condition(s) become true,
+ *    using xsl:break instruction. xsl:break being the final instruction (if invoked) 
+ *    processed by xsl:iterate, can also specify particular XSLT evaluation to be 
+ *    done via xsl:break's "select" attribute or with XSLT contents within xsl:break. 
+ * 3) With xsl:iterate instruction, the stylesheet author could also specify, 
+ *    particular XSLT processing to be done via xsl:on-completion instruction,
+ *    after input sequence is exhausted. xsl:on-completion instruction is not
+ *    invoked, when xsl:iterate processing is exited via xsl:break instruction.
+ *    xsl:on-completion instruction can specify certain XSLT processing to be done,
+ *    via its "select" attribute or via XSLT contents within xsl:on-completion.
+ * 4) xsl:iterate can also have optional xsl:param elements, to allow passing 
+ *    certain values as arguments to body of xsl:iterate (upon initial invocation of 
+ *    xsl:iterate, or via xsl:next-iteration element just before a new iteration shall 
+ *    start).
+ * 5) The effect of xsl:iterate may also be achieved by XSLT 1.0 compatible named 
+ *    templates. But using xsl:iterate likely makes writing such XSLT processing 
+ *    simpler. 
  */
 public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
 {
@@ -65,6 +92,10 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
      private static final long serialVersionUID = -2692900882677332482L;
      
      private static final String OTHER_ELEM = "OTHER_ELEM";
+              
+     private List<ParamWithParmData> fParamList = new ArrayList<ParamWithParmData>();
+     
+     private List<ParamWithParmData> fWithParamList = new ArrayList<ParamWithParmData>();
 
      /**
       * Construct an element representing xsl:iterate.
@@ -78,7 +109,7 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
 
      public void setSelect(XPath xpath)
      {
-         m_selectExpression = xpath.getExpression();   
+         m_selectExpression = xpath.getExpression();
      }
 
      /**
@@ -121,6 +152,7 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
          java.util.Vector vnames = sroot.getComposeState().getVariableNames();
 
          if (m_selectExpression != null) {
+             
              m_selectExpression.fixupVariables(vnames, sroot.getComposeState().
                                                                   getGlobalsSize());
          }
@@ -178,8 +210,7 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
        * 
        * @xsl.usage advanced
        */
-       public void transformSelectedNodes(TransformerImpl transformer) throws 
-                                                                 TransformerException {
+       public void transformSelectedNodes(TransformerImpl transformer) throws TransformerException {
     
            final XPathContext xctxtOriginal = transformer.getXPathContext();
         
@@ -218,21 +249,32 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
                        docID = child & DTMManager.IDENT_DTM_DEFAULT;
                    }                                  
                    
-                   for (ElemTemplateElement elemTemplate = this.m_firstChild; 
-                                                          elemTemplate != null; 
-                                                          elemTemplate = elemTemplate.m_nextSibling) {
+                   for (ElemTemplateElement elemTemplate = this.m_firstChild; elemTemplate != null; 
+                                                                          elemTemplate = elemTemplate.m_nextSibling) {
                        if ((elemTemplate instanceof ElemIterateOnCompletion) && 
                                                                         (xslOnCompletionTemplate == null)) {
                            xslOnCompletionTemplate = (ElemIterateOnCompletion)elemTemplate;     
                        }
+                       else if (elemTemplate instanceof ElemIterateNextIteration) {
+                           VariableStack varStack = xctxt.getVarStack();
+                           for (int idx = 0; idx < fWithParamList.size(); idx++) {
+                               ParamWithParmData withParamData = fWithParamList.get(idx);
+                               XPath withParamSelectVal = withParamData.getSelectVal();                               
+                               XObject evalResult = withParamSelectVal.execute(xctxt, child, 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);
+                           }                           
+                       }
                        
                        if (!((XslTransformErrorLocatorHelper.isXslIterateBreakEvaluated).booleanValue())) {
-                          xctxt.setSAXLocator(elemTemplate);
-                          transformer.setCurrentElement(elemTemplate);
-                          elemTemplate.execute(transformer);
+                           xctxt.setSAXLocator(elemTemplate);
+                           transformer.setCurrentElement(elemTemplate);
+                           elemTemplate.execute(transformer);
                        }
                        else {
-                          break;    
+                           break;    
                        }
                    }
                    
@@ -280,17 +322,8 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
           for (ElemTemplateElement elemTemplate = this.m_firstChild; 
                                                              elemTemplate != null; 
                                                              elemTemplate = elemTemplate.m_nextSibling) {
-              if ((elemTemplate instanceof ElemUnknown) && ((Constants.ELEMNAME_PARAMVARIABLE_STRING).
-                                                                                    equals(elemTemplate.getLocalName()))) {
-                  // revisit.
-                  // currently, 'elemTemplate instanceof ElemParam' is evaluated as false but 'elemTemplate 
-                  // instanceof ElemUnknown' is evaluated as true when this "if" condition was evaluated.                  
+              if (elemTemplate instanceof ElemParam) {                  
                   xslElemNamesList.add(Constants.ELEMNAME_PARAMVARIABLE_STRING);
-                  
-                  // ElemUnknown elemUnknown = (ElemUnknown)elemTemplate;
-                  // String nameVal = elemUnknown.getAttribute("name");
-                  // String selectVal = elemUnknown.getAttribute("select");
-                  // NodeList nodeList = elemUnknown.getChildNodes();
               }
               else if (elemTemplate instanceof ElemIterateOnCompletion) {
                   xslElemNamesList.add(Constants.ELEMNAME_ITERATE_ONCOMPLETION_STRING);   
@@ -336,6 +369,112 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
               throw new TransformerException("XTSE3120 : an xsl:next-iteration element when present, must be the last instruction within "
                                                                                          + "an xsl:iterate loop.", xctxt.getSAXLocator());
           }
+          
+          // Validate the, xsl:iterate->xsl:param* and xsl:next-iteration->xsl:with-param* names, as per following XSLT 3.0 
+          // spec requirements,
+          // 1) All the xsl:param names must be unique.
+          // 2) All the xsl:next-iteration->xsl:with-param names must be unique.  
+          // 3) Value of name attribute of xsl:param's must be pair-wise equal to value of name attribute of 
+          //    xsl:next-iteration->xsl:with-param.          
+          if (paramIdx != -1) {
+              for (ElemTemplateElement elemTemplate = this.m_firstChild; elemTemplate != null; 
+                                                                                 elemTemplate = elemTemplate.m_nextSibling) {
+                  if (elemTemplate instanceof ElemParam) {
+                     ElemParam paramElem = (ElemParam)elemTemplate;
+                     QName paramNameVal = paramElem.getName();
+                     XPath paramSelectXPath = paramElem.getSelect();
+                     ParamWithParmData paramWithParmDataObj = new ParamWithParmData();
+                     paramWithParmDataObj.setNameVal(paramNameVal);
+                     paramWithParmDataObj.setSelectVal(paramSelectXPath);
+                     if (fParamList.contains(paramWithParmDataObj)) {
+                         throw new TransformerException("XTSE0580 : the name of the xsl:param parameter '" + paramNameVal + "' "
+                                                                                         + "is not unique.", xctxt.getSAXLocator());    
+                     }
+                     else {
+                         fParamList.add(paramWithParmDataObj);    
+                     }
+                  } 
+                  else if (elemTemplate instanceof ElemIterateNextIteration) {
+                      ElemIterateNextIteration elemIterateNextIteration = (ElemIterateNextIteration)elemTemplate;
+                      NodeList nextIterationChildNodes = elemIterateNextIteration.getChildNodes();
+                      for (int idx = 0; idx < nextIterationChildNodes.getLength(); idx++) {
+                          Node nextIterChild = nextIterationChildNodes.item(idx);
+                          if (nextIterChild instanceof ElemWithParam) {
+                              ElemWithParam withParamElem = (ElemWithParam)nextIterChild;
+                              QName withParamNameVal = withParamElem.getName();
+                              XPath withParamSelectXPath = withParamElem.getSelect();                              
+                              ParamWithParmData paramWithParmDataObj = new ParamWithParmData();
+                              paramWithParmDataObj.setNameVal(withParamNameVal);
+                              paramWithParmDataObj.setSelectVal(withParamSelectXPath);
+                              if (fWithParamList.contains(paramWithParmDataObj)) {
+                                 throw new TransformerException("XTSE0670 : duplicate xsl:with-param parameter name '" + withParamNameVal + 
+                                                                                                                      "'", xctxt.getSAXLocator());   
+                              }
+                              else {
+                                 fWithParamList.add(paramWithParmDataObj);  
+                              }
+                          }
+                      }
+                  }                  
+              }
+              
+              if (fParamList.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());     
+              }
+              else {
+                 for (int idx = 0; idx < fParamList.size(); idx ++) {
+                     ParamWithParmData paramData = fParamList.get(idx);
+                     ParamWithParmData 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());        
+                     }
+                 }
+              }
+          }
+          
+      }
+      
+      /*
+       * An object of this class, stores information about, one xsl:param 
+       * element or one xsl:next-iteration->xsl:with-param element, for a 
+       * particular xsl:iterate instruction. 
+       */
+      class ParamWithParmData {
+          
+          public QName nameVal;
+          
+          public XPath selectVal;
+
+          public QName getNameVal() {
+              return nameVal;
+          }
+
+          public void setNameVal(QName nameVal) {
+              this.nameVal = nameVal;
+          }
+
+          public XPath getSelectVal() {
+              return selectVal;
+          }
+
+          public void setSelectVal(XPath selectVal) {
+              this.selectVal = selectVal;
+          }
+          
+          @Override
+          public boolean equals(Object obj) {
+              if (this == obj) {
+                  return true;
+              }
+              if (obj == null || getClass() != obj.getClass()) {
+                  return false;
+              }
+              ParamWithParmData paramWithParmData = (ParamWithParmData)obj;
+              return nameVal.equals(paramWithParmData.getNameVal());
+          }
+          
       }
       
 }
diff --git a/tests/org/apache/xalan/xslt3/XslIterateTests.java b/tests/org/apache/xalan/xslt3/XslIterateTests.java
index 1afec217..48230885 100644
--- a/tests/org/apache/xalan/xslt3/XslIterateTests.java
+++ b/tests/org/apache/xalan/xslt3/XslIterateTests.java
@@ -130,5 +130,45 @@ public class XslIterateTests extends XslTransformTestsUtil {
         runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, 
                                                             new XslTestsErrorHandler());
     }
+    
+    @Test
+    public void xslIterateTest9() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "iterate001.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "iterate-002.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "iterate-002.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslIterateTest10() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "iterate001.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "iterate-003.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "iterate-003.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslIterateTest11() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test9.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test9.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test9.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslIterateTest12() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test10.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test10.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test10.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
 
 }
diff --git a/tests/xsl_iterate/gold/iterate-002.out b/tests/xsl_iterate/gold/iterate-002.out
new file mode 100644
index 00000000..6a58fb61
--- /dev/null
+++ b/tests/xsl_iterate/gold/iterate-002.out
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?><out>
+  <item cost="00.00">
+    <TITLE>Pride and Prejudice</TITLE>
+  </item>
+  <item cost="04.95">
+    <TITLE>Wuthering Heights</TITLE>
+  </item>
+  <item cost="11.53">
+    <TITLE>Tess of the d'Urbervilles</TITLE>
+  </item>
+  <item cost="16.48">
+    <TITLE>Jude the Obscure</TITLE>
+  </item>
+  <item cost="21.43">
+    <TITLE>The Big Over Easy</TITLE>
+  </item>
+  <item cost="37.90">
+    <TITLE>The Eyre Affair</TITLE>
+  </item>
+</out>
diff --git a/tests/xsl_iterate/gold/iterate-003.out b/tests/xsl_iterate/gold/iterate-003.out
new file mode 100644
index 00000000..493a8346
--- /dev/null
+++ b/tests/xsl_iterate/gold/iterate-003.out
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?><out>
+  <item cost="00.00">
+    <TITLE>Pride and Prejudice</TITLE>
+  </item>
+  <item cost="04.95">
+    <TITLE>Wuthering Heights</TITLE>
+  </item>
+  <item cost="11.53">
+    <TITLE>Tess of the d'Urbervilles</TITLE>
+  </item>
+</out>
diff --git a/tests/xsl_iterate/gold/test10.out b/tests/xsl_iterate/gold/test10.out
new file mode 100644
index 00000000..12642692
--- /dev/null
+++ b/tests/xsl_iterate/gold/test10.out
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><result numberRange="start : 1, end : 10">10 :: 20</result>
diff --git a/tests/xsl_iterate/gold/test9.out b/tests/xsl_iterate/gold/test9.out
new file mode 100644
index 00000000..37a8b81e
--- /dev/null
+++ b/tests/xsl_iterate/gold/test9.out
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><result endNum="1520" startNum="1024">Total numbers within range : 497</result>
diff --git a/tests/xsl_iterate/iterate-002.xsl b/tests/xsl_iterate/iterate-002.xsl
new file mode 100644
index 00000000..62dd2dc1
--- /dev/null
+++ b/tests/xsl_iterate/iterate-002.xsl
@@ -0,0 +1,47 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="3.0">
+   
+   <!-- use with iterate001.xml -->
+   
+   <!-- An XSLT stylesheet test case, that uses xsl:iterate 
+        along with xsl:param and xsl:next-iteration.
+       
+        This XSLT stylesheet has been borrowed from W3C XSLT 
+        3.0 test suite and makes few changes to XSLT stylesheet 
+        syntax. --> 
+       
+  <xsl:output method="xml" indent="yes"/>
+  
+  <xsl:template match="/">
+      <out>
+        <xsl:iterate select="//ITEM">
+          <xsl:param name="basketCost" select="0"/>
+          <item cost="{format-number($basketCost, '00.00')}">
+             <xsl:copy-of select="TITLE"/>
+          </item>
+          <xsl:next-iteration>
+             <xsl:with-param name="basketCost" select="$basketCost + PRICE"/>
+          </xsl:next-iteration>
+        </xsl:iterate>
+      </out>
+  </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/iterate-003.xsl b/tests/xsl_iterate/iterate-003.xsl
new file mode 100644
index 00000000..83c9e36a
--- /dev/null
+++ b/tests/xsl_iterate/iterate-003.xsl
@@ -0,0 +1,56 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="3.0">
+                
+  <!-- use with iterate001.xml -->
+   
+  <!-- An XSLT stylesheet test case, that uses xsl:iterate 
+       along with xsl:param and xsl:next-iteration. This
+       XSLT stylesheet uses xsl:break instruction to exit
+       from xsl:iterate loop early.  
+       
+       This XSLT stylesheet has been borrowed from W3C XSLT 
+       3.0 test suite and makes few changes to XSLT stylesheet 
+       syntax. -->
+        
+  <xsl:output method="xml" indent="yes"/>                
+
+  <xsl:template match="/">
+    <out>
+      <xsl:iterate select="//ITEM">
+        <xsl:param name="basketCost" select="0"/>
+        <xsl:choose>
+          <xsl:when test="$basketCost &gt; 12.00">
+            <xsl:break/>
+          </xsl:when>
+          <xsl:otherwise>
+            <item cost="{format-number($basketCost, '00.00')}">
+              <xsl:copy-of select="TITLE"/>
+            </item>            
+          </xsl:otherwise>
+        </xsl:choose>
+        <xsl:next-iteration>
+	   <xsl:with-param name="basketCost" select="$basketCost + PRICE"/>
+        </xsl:next-iteration>
+      </xsl:iterate>
+    </out>
+  </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/iterate001.xml b/tests/xsl_iterate/iterate001.xml
new file mode 100644
index 00000000..2354e199
--- /dev/null
+++ b/tests/xsl_iterate/iterate001.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0"?>
+<!-- this XML document is borrowed from, W3C's XSLT 3.0 test suite. -->
+<BOOKLIST>
+<BOOKS>
+	<ITEM CAT="MMP">
+    	<TITLE>Pride and Prejudice</TITLE>
+    	<AUTHOR>Jane Austen</AUTHOR>
+    	<PUBLISHER>Modern Library</PUBLISHER>
+    	<PUB-DATE>2002-12-31</PUB-DATE>
+    	<LANGUAGE>English</LANGUAGE>
+    	<PRICE>4.95</PRICE>
+    	<QUANTITY>187</QUANTITY>
+    	<ISBN>0679601686</ISBN>
+    	<PAGES>352</PAGES>
+    	<DIMENSIONS UNIT="in">8.3 5.7 1.1</DIMENSIONS>
+    	<WEIGHT UNIT="oz">6.1</WEIGHT>
+	</ITEM>
+	<ITEM CAT="P">
+		<TITLE>Wuthering Heights</TITLE>
+		<AUTHOR>Charlotte Bront&#xeb;</AUTHOR>
+		<PUBLISHER>Penguin Classics</PUBLISHER>
+		<PUB-DATE>2002-12-31</PUB-DATE>
+		<LANGUAGE>English</LANGUAGE>
+		<PRICE>6.58</PRICE>
+		<QUANTITY>113</QUANTITY>		
+		<ISBN>0141439556</ISBN>
+		<PAGES>430</PAGES>
+        <DIMENSIONS UNIT="in">1.0 5.2 7.8</DIMENSIONS>
+		<WEIGHT UNIT="oz">11.2</WEIGHT>
+	</ITEM>
+	<ITEM CAT="P">
+		<TITLE>Tess of the d'Urbervilles</TITLE>
+		<AUTHOR>Thomas Hardy</AUTHOR>
+		<PUBLISHER>Bantam Classics</PUBLISHER>
+		<PUB-DATE>1984-05-01</PUB-DATE>
+		<LANGUAGE>English</LANGUAGE>
+		<PRICE>4.95</PRICE>
+		<QUANTITY>85</QUANTITY>		
+		<ISBN>0553211684</ISBN>
+		<PAGES>480</PAGES>
+        <DIMENSIONS UNIT="in">6.8 4.2 0.8</DIMENSIONS>
+		<WEIGHT UNIT="oz">7.7</WEIGHT>
+	</ITEM>
+	<ITEM CAT="P">
+		<TITLE>Jude the Obscure</TITLE>
+		<AUTHOR>Thomas Hardy</AUTHOR>
+		<PUBLISHER>Penguin Classics</PUBLISHER>
+		<PUB-DATE>1998-09-01</PUB-DATE>
+		<LANGUAGE>English</LANGUAGE>
+		<PRICE>4.95</PRICE>
+		<QUANTITY>129</QUANTITY>		
+		<ISBN>0140435387</ISBN>
+		<PAGES>528</PAGES>
+        <DIMENSIONS UNIT="in">7.8 5.2 0.9</DIMENSIONS>
+		<WEIGHT UNIT="oz">10.9</WEIGHT>
+	</ITEM>
+	<ITEM CAT="H">
+		<TITLE>The Big Over Easy</TITLE>
+		<AUTHOR>Jasper Fforde</AUTHOR>
+		<PUBLISHER>Hodder &amp; Stoughton</PUBLISHER>
+		<PUB-DATE>2005-07-11</PUB-DATE>
+		<LANGUAGE>English</LANGUAGE>
+		<PRICE>16.47</PRICE>
+		<QUANTITY>129</QUANTITY>		
+		<ISBN>0340835672</ISBN>
+		<PAGES>346</PAGES>
+        <DIMENSIONS UNIT="cm">22.5 18.0 3.5</DIMENSIONS>
+		<WEIGHT UNIT="g">390</WEIGHT>
+	</ITEM>
+	<ITEM CAT="P">
+		<TITLE>The Eyre Affair</TITLE>
+		<AUTHOR>Jasper Fforde</AUTHOR>
+		<PUBLISHER>Penguin</PUBLISHER>
+		<PUB-DATE>2003-02-25</PUB-DATE>
+		<LANGUAGE>English</LANGUAGE>
+		<PRICE>16.47</PRICE>
+		<QUANTITY>129</QUANTITY>		
+		<ISBN>0142001805</ISBN>
+		<PAGES>384</PAGES>
+        <DIMENSIONS UNIT="in">7.8 5.0 0.9</DIMENSIONS>
+		<WEIGHT UNIT="oz">9.0</WEIGHT>
+	</ITEM>
+</BOOKS>
+<CATEGORIES DESC="Miscellaneous categories">
+    <CATEGORY CODE="P" DESC="Paperback"/>
+    <CATEGORY CODE="MMP" DESC="Mass-market Paperback"/>
+    <CATEGORY CODE="H" DESC="Hard Cover"/>
+</CATEGORIES>
+</BOOKLIST>
diff --git a/tests/xsl_iterate/test10.xsl b/tests/xsl_iterate/test10.xsl
new file mode 100644
index 00000000..0ae5b91a
--- /dev/null
+++ b/tests/xsl_iterate/test10.xsl
@@ -0,0 +1,54 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="3.0">
+                
+  <!-- Author: mukulg@apache.org -->
+   
+  <!-- An XSLT stylesheet test case, that uses xsl:iterate 
+       having xsl:param, to do primitive mathematical analysis 
+       on a sequence of numbers. This stylesheet, uses more than 
+       one xsl:param element with xsl:iterate.-->                
+
+  <xsl:output method="xml" indent="yes"/>
+  
+  <xsl:variable name="x" select="1"/>  
+  <xsl:variable name="y" select="10"/>
+  
+  <xsl:variable name="numberList">
+     <xsl:for-each select="$x to $y">
+       <val><xsl:value-of select="."/></val>
+     </xsl:for-each>
+  </xsl:variable>
+  
+  <xsl:template match="/">
+     <result numberRange="start : {$x}, end : {$y}">
+        <xsl:iterate select="$numberList/val">
+           <xsl:param name="count1" select="0"/>
+           <xsl:param name="count2" select="0"/>
+           <xsl:on-completion select="concat($count1, ' :: ', $count2)"/>
+           <xsl:next-iteration>
+              <xsl:with-param name="count1" select="$count1 + 1"/>
+              <xsl:with-param name="count2" select="$count2 + 2"/>
+           </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>
diff --git a/tests/xsl_iterate/test9.xsl b/tests/xsl_iterate/test9.xsl
new file mode 100644
index 00000000..5f71c91b
--- /dev/null
+++ b/tests/xsl_iterate/test9.xsl
@@ -0,0 +1,51 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="3.0">
+                
+  <!-- Author: mukulg@apache.org -->
+   
+  <!-- An XSLT stylesheet test case, that uses xsl:iterate 
+       having xsl:param, to do primitive mathematical analysis 
+       on a sequence of numbers.  -->                 
+
+  <xsl:output method="xml" indent="yes"/>
+  
+  <xsl:variable name="x" select="1024"/>  
+  <xsl:variable name="y" select="1520"/>
+  
+  <xsl:variable name="numberList">
+     <xsl:for-each select="$x to $y">
+       <val><xsl:value-of select="."/></val>
+     </xsl:for-each>
+  </xsl:variable>
+  
+  <xsl:template match="/">
+     <result startNum="{$x}" endNum="{$y}">
+        <xsl:iterate select="$numberList/val">
+           <xsl:param name="count" select="0"/>
+           <xsl:on-completion select="concat('Total numbers within range : ', $count)"/>                       
+           <xsl:next-iteration>
+              <xsl:with-param name="count" select="$count + 1"/>
+           </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>


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