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 > 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ë</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 & 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