You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by mu...@apache.org on 2023/06/12 13:31:32 UTC
[xalan-java] branch xalan-j_xslt3.0 updated: implementing xslt 3.0's xsl:on-completion instruction for xsl:iterate. committing few minor related codebase changes as well. also committing few new relevant working test cases.
This is an automated email from the ASF dual-hosted git repository.
mukulg pushed a commit to branch xalan-j_xslt3.0
in repository https://gitbox.apache.org/repos/asf/xalan-java.git
The following commit(s) were added to refs/heads/xalan-j_xslt3.0 by this push:
new a768cf51 implementing xslt 3.0's xsl:on-completion instruction for xsl:iterate. committing few minor related codebase changes as well. also committing few new relevant working test cases.
a768cf51 is described below
commit a768cf510256a03f70440573664a7b0f022fa10d
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Mon Jun 12 19:01:17 2023 +0530
implementing xslt 3.0's xsl:on-completion instruction for xsl:iterate. committing few minor related codebase changes as well. also committing few new relevant working test cases.
---
src/org/apache/xalan/templates/ElemIterate.java | 28 ++++++++++--
.../apache/xalan/templates/ElemIterateBreak.java | 6 +--
.../xalan/templates/ElemIterateOnCompletion.java | 52 +++++++++++++++++++--
.../xslt/util/XslTransformErrorLocatorHelper.java | 2 +
src/org/apache/xpath/functions/FuncLast.java | 7 +++
src/org/apache/xpath/functions/FuncPosition.java | 13 +++++-
tests/org/apache/xalan/xslt3/XslIterateTests.java | 53 ++++++++++++++++++++++
tests/xsl_iterate/gold/test4.out | 10 ++++
tests/xsl_iterate/gold/test6.out | 1 +
tests/xsl_iterate/gold/test7.out | 0
tests/xsl_iterate/test4.xsl | 42 +++++++++++++++++
tests/xsl_iterate/test5.xsl | 49 ++++++++++++++++++++
tests/xsl_iterate/test6.xsl | 49 ++++++++++++++++++++
tests/xsl_iterate/test7.xsl | 43 ++++++++++++++++++
tests/xsl_iterate/test8.xsl | 43 ++++++++++++++++++
15 files changed, 383 insertions(+), 15 deletions(-)
diff --git a/src/org/apache/xalan/templates/ElemIterate.java b/src/org/apache/xalan/templates/ElemIterate.java
index cea1e7d3..572c1e6d 100644
--- a/src/org/apache/xalan/templates/ElemIterate.java
+++ b/src/org/apache/xalan/templates/ElemIterate.java
@@ -205,7 +205,10 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
transformer.pushElemTemplateElement(null);
int docID = sourceNode & DTMManager.IDENT_DTM_DEFAULT;
- int child;
+ int child;
+
+ ElemIterateOnCompletion xslOnCompletionTemplate = null;
+
while ((child = sourceNodes.nextNode()) != DTM.NULL) {
currentNodes.setTop(child);
currentExpressionNodes.setTop(child);
@@ -218,6 +221,11 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
for (ElemTemplateElement elemTemplate = this.m_firstChild;
elemTemplate != null;
elemTemplate = elemTemplate.m_nextSibling) {
+ if ((elemTemplate instanceof ElemIterateOnCompletion) &&
+ (xslOnCompletionTemplate == null)) {
+ xslOnCompletionTemplate = (ElemIterateOnCompletion)elemTemplate;
+ }
+
if (!((XslTransformErrorLocatorHelper.isXslIterateBreakEvaluated).booleanValue())) {
xctxt.setSAXLocator(elemTemplate);
transformer.setCurrentElement(elemTemplate);
@@ -228,11 +236,21 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
}
}
- if ((XslTransformErrorLocatorHelper.isXslIterateBreakEvaluated).booleanValue()) {
- XslTransformErrorLocatorHelper.isXslIterateBreakEvaluated = Boolean.FALSE;
+ if ((XslTransformErrorLocatorHelper.isXslIterateBreakEvaluated).booleanValue()) {
break;
}
}
+
+ if ((xslOnCompletionTemplate != null) && !(XslTransformErrorLocatorHelper.
+ isXslIterateBreakEvaluated).booleanValue()) {
+ XslTransformErrorLocatorHelper.isXslIterateOnCompletionActive = Boolean.TRUE;
+ xctxt.setSAXLocator(xslOnCompletionTemplate);
+ transformer.setCurrentElement(xslOnCompletionTemplate);
+ xslOnCompletionTemplate.execute(transformer);
+ XslTransformErrorLocatorHelper.isXslIterateOnCompletionActive = Boolean.FALSE;
+ }
+
+ XslTransformErrorLocatorHelper.isXslIterateBreakEvaluated = Boolean.FALSE;
}
finally {
xctxt.popSAXLocator();
@@ -266,7 +284,7 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
equals(elemTemplate.getLocalName()))) {
// revisit.
// currently, 'elemTemplate instanceof ElemParam' is evaluated as false but 'elemTemplate
- // instanceof ElemUnknown' is evaluated as true within this "if" condition.
+ // instanceof ElemUnknown' is evaluated as true when this "if" condition was evaluated.
xslElemNamesList.add(Constants.ELEMNAME_PARAMVARIABLE_STRING);
// ElemUnknown elemUnknown = (ElemUnknown)elemTemplate;
@@ -286,7 +304,7 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
}
// get index of specific item's first occurrence with the list object 'xslElemNamesList'.
- // if a particular kind of item that is checked is not present within the list object
+ // if a particular kind of xdm item that is checked is not present within the list object
// 'xslElemNamesList', its index is returned as -1.
int paramIdx = xslElemNamesList.indexOf(Constants.ELEMNAME_PARAMVARIABLE_STRING);
int onCompletionIdx = xslElemNamesList.indexOf(Constants.ELEMNAME_ITERATE_ONCOMPLETION_STRING);
diff --git a/src/org/apache/xalan/templates/ElemIterateBreak.java b/src/org/apache/xalan/templates/ElemIterateBreak.java
index 6ee9ade1..2135d561 100644
--- a/src/org/apache/xalan/templates/ElemIterateBreak.java
+++ b/src/org/apache/xalan/templates/ElemIterateBreak.java
@@ -160,9 +160,9 @@ public class ElemIterateBreak extends ElemTemplateElement implements ExpressionO
+ "stylesheet element as its following sibling.",
xpathContext.getSAXLocator());
}
- else {
+ else {
+ transformXslBreakInstruction(transformer);
XslTransformErrorLocatorHelper.isXslIterateBreakEvaluated = Boolean.TRUE;
- transformSelectedNodes(transformer);
}
}
@@ -173,7 +173,7 @@ public class ElemIterateBreak extends ElemTemplateElement implements ExpressionO
*
* @xsl.usage advanced
*/
- public void transformSelectedNodes(TransformerImpl transformer) throws
+ public void transformXslBreakInstruction(TransformerImpl transformer) throws
TransformerException {
XPathContext xctxt = transformer.getXPathContext();
diff --git a/src/org/apache/xalan/templates/ElemIterateOnCompletion.java b/src/org/apache/xalan/templates/ElemIterateOnCompletion.java
index f0968533..3c69b392 100644
--- a/src/org/apache/xalan/templates/ElemIterateOnCompletion.java
+++ b/src/org/apache/xalan/templates/ElemIterateOnCompletion.java
@@ -20,9 +20,15 @@ package org.apache.xalan.templates;
import javax.xml.transform.TransformerException;
import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xalan.xslt.util.XslTransformErrorLocatorHelper;
+import org.apache.xml.serializer.SerializationHandler;
import org.apache.xpath.Expression;
import org.apache.xpath.ExpressionOwner;
import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.xml.sax.SAXException;
+
+import com.sun.org.apache.xml.internal.dtm.DTM;
/**
* XSLT 3.0 xsl:on-completion element.
@@ -50,6 +56,8 @@ public class ElemIterateOnCompletion extends ElemTemplateElement implements Expr
* Construct an element representing xsl:on-completion.
*/
public ElemIterateOnCompletion() {}
+
+ private String xpathSelectPatternStr;
/**
* The "select" expression.
@@ -58,7 +66,8 @@ public class ElemIterateOnCompletion extends ElemTemplateElement implements Expr
public void setSelect(XPath xpath)
{
- m_selectExpression = xpath.getExpression();
+ m_selectExpression = xpath.getExpression();
+ xpathSelectPatternStr = xpath.getPatternString();
}
/**
@@ -148,7 +157,7 @@ public class ElemIterateOnCompletion extends ElemTemplateElement implements Expr
*/
public void execute(TransformerImpl transformer) throws TransformerException
{
- transformSelectedNodes(transformer);
+ transformXslOncompletionInstruction(transformer);
}
/**
@@ -158,9 +167,42 @@ public class ElemIterateOnCompletion extends ElemTemplateElement implements Expr
*
* @xsl.usage advanced
*/
- public void transformSelectedNodes(TransformerImpl transformer) throws
- TransformerException {
- // TO DO
+ public void transformXslOncompletionInstruction(TransformerImpl transformer) throws
+ TransformerException {
+
+ if ((XslTransformErrorLocatorHelper.isXslIterateOnCompletionActive).booleanValue()) {
+ final XPathContext originalXctxt = transformer.getXPathContext();
+
+ XPathContext xctxt = transformer.getXPathContext();
+
+ // during evaluation of xsl:on-completion, the context item is absent.
+ // we make following two changes to XPath context to ensure this.
+ xctxt.pushCurrentNode(DTM.NULL);
+ xctxt.pushCurrentExpressionNode(DTM.NULL);
+
+ if (xpathSelectPatternStr != null) {
+ SerializationHandler rth = transformer.getResultTreeHandler();
+
+ try {
+ m_selectExpression.executeCharsToContentHandler(xctxt, rth);
+ } catch (TransformerException ex) {
+ throw ex;
+ } catch (SAXException ex) {
+ throw new TransformerException(ex);
+ }
+ }
+ else {
+ for (ElemTemplateElement elemTemplate = this.m_firstChild; elemTemplate != null;
+ elemTemplate = elemTemplate.m_nextSibling) {
+ xctxt.setSAXLocator(elemTemplate);
+ transformer.setCurrentElement(elemTemplate);
+ elemTemplate.execute(transformer);
+ }
+ }
+
+ // restore the XPath original context, on current XSLT transformer object
+ transformer.setXPathContext(originalXctxt);
+ }
}
}
diff --git a/src/org/apache/xalan/xslt/util/XslTransformErrorLocatorHelper.java b/src/org/apache/xalan/xslt/util/XslTransformErrorLocatorHelper.java
index 06ce48d5..9b6399b3 100644
--- a/src/org/apache/xalan/xslt/util/XslTransformErrorLocatorHelper.java
+++ b/src/org/apache/xalan/xslt/util/XslTransformErrorLocatorHelper.java
@@ -30,5 +30,7 @@ public class XslTransformErrorLocatorHelper {
public static String systemId;
public static Boolean isXslIterateBreakEvaluated = Boolean.FALSE;
+
+ public static Boolean isXslIterateOnCompletionActive = Boolean.FALSE;
}
diff --git a/src/org/apache/xpath/functions/FuncLast.java b/src/org/apache/xpath/functions/FuncLast.java
index bf3eb9ac..09fae2dc 100644
--- a/src/org/apache/xpath/functions/FuncLast.java
+++ b/src/org/apache/xpath/functions/FuncLast.java
@@ -20,6 +20,7 @@
*/
package org.apache.xpath.functions;
+import org.apache.xml.dtm.DTM;
import org.apache.xml.dtm.DTMIterator;
import org.apache.xpath.XPathContext;
import org.apache.xpath.axes.SubContextList;
@@ -63,6 +64,12 @@ public class FuncLast extends Function
if (xctxt.getXPath3ContextSize() != -1) {
return xctxt.getXPath3ContextSize();
}
+
+ if (xctxt.getContextNode() == DTM.NULL) {
+ throw new javax.xml.transform.TransformerException("XPDY0002 : The context item is absent "
+ + "at this point, and therefore last() function "
+ + "cannot be called.", xctxt.getSAXLocator());
+ }
// assert(null != m_contextNodeList, "m_contextNodeList must be non-null");
// If we're in a predicate, then this will return non-null.
diff --git a/src/org/apache/xpath/functions/FuncPosition.java b/src/org/apache/xpath/functions/FuncPosition.java
index b5e6f1a3..36f7c15e 100644
--- a/src/org/apache/xpath/functions/FuncPosition.java
+++ b/src/org/apache/xpath/functions/FuncPosition.java
@@ -20,6 +20,8 @@
*/
package org.apache.xpath.functions;
+import javax.xml.transform.TransformerException;
+
import org.apache.xml.dtm.DTM;
import org.apache.xml.dtm.DTMIterator;
import org.apache.xpath.XPathContext;
@@ -55,14 +57,21 @@ public class FuncPosition extends Function
*
* @return The current position of the iteration in the context node list,
* or -1 if there is no active context node list.
+ * @throws TransformerException
*/
- public int getPositionInContextNodeList(XPathContext xctxt)
+ public int getPositionInContextNodeList(XPathContext xctxt) throws TransformerException
{
if (xctxt.getXPath3ContextPosition() != -1) {
return xctxt.getXPath3ContextPosition();
}
+ if (xctxt.getContextNode() == DTM.NULL) {
+ throw new javax.xml.transform.TransformerException("XPDY0002 : The context item is absent "
+ + "at this point, and therefore position() function "
+ + "cannot be called.", xctxt.getSAXLocator());
+ }
+
// System.out.println("FuncPosition- entry");
// If we're in a predicate, then this will return non-null.
SubContextList iter = m_isTopLevel ? null : xctxt.getSubContextList();
@@ -124,7 +133,7 @@ public class FuncPosition extends Function
* @throws javax.xml.transform.TransformerException
*/
public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
- {
+ {
double pos = (double) getPositionInContextNodeList(xctxt);
return new XNumber(pos);
diff --git a/tests/org/apache/xalan/xslt3/XslIterateTests.java b/tests/org/apache/xalan/xslt3/XslIterateTests.java
index 573fa976..1afec217 100644
--- a/tests/org/apache/xalan/xslt3/XslIterateTests.java
+++ b/tests/org/apache/xalan/xslt3/XslIterateTests.java
@@ -16,6 +16,7 @@
*/
package org.apache.xalan.xslt3;
+import org.apache.xalan.util.XslTestsErrorHandler;
import org.apache.xalan.util.XslTransformTestsUtil;
import org.junit.AfterClass;
import org.junit.BeforeClass;
@@ -77,5 +78,57 @@ public class XslIterateTests extends XslTransformTestsUtil {
runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
}
+
+ @Test
+ public void xslIterateTest4() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test4.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test4.out";
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
+
+ @Test
+ public void xslIterateTest5() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test5.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test4.out";
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
+
+ @Test
+ public void xslIterateTest6() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test6.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test6.out";
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
+
+ @Test
+ public void xslIterateTest7() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test7.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test7.out";
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath,
+ new XslTestsErrorHandler());
+ }
+
+ @Test
+ public void xslIterateTest8() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test8.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test7.out";
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath,
+ new XslTestsErrorHandler());
+ }
}
diff --git a/tests/xsl_iterate/gold/test4.out b/tests/xsl_iterate/gold/test4.out
new file mode 100644
index 00000000..7c34280d
--- /dev/null
+++ b/tests/xsl_iterate/gold/test4.out
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <item>hello1</item>
+ <item>hello2</item>
+ <item>hello3</item>
+ <item>hello4</item>
+ <item>hello5</item>
+ <item>hello6</item>
+ <item>hello7</item>
+ <allItemsProcessedWithoutBreak/>
+</result>
diff --git a/tests/xsl_iterate/gold/test6.out b/tests/xsl_iterate/gold/test6.out
new file mode 100644
index 00000000..a19077d4
--- /dev/null
+++ b/tests/xsl_iterate/gold/test6.out
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><result/>
diff --git a/tests/xsl_iterate/gold/test7.out b/tests/xsl_iterate/gold/test7.out
new file mode 100644
index 00000000..e69de29b
diff --git a/tests/xsl_iterate/test4.xsl b/tests/xsl_iterate/test4.xsl
new file mode 100644
index 00000000..74dcf787
--- /dev/null
+++ b/tests/xsl_iterate/test4.xsl
@@ -0,0 +1,42 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- use with test1_a.xml -->
+
+ <!-- An XSLT stylesheet test, demonstrating use of xsl:iterate
+ with xsl:on-completion. -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:template match="/elem">
+ <result>
+ <xsl:iterate select="a">
+ <xsl:on-completion>
+ <allItemsProcessedWithoutBreak/>
+ </xsl:on-completion>
+ <item><xsl:value-of select="."/></item>
+ </xsl:iterate>
+ </result>
+ </xsl:template>
+
+ <!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+</xsl:stylesheet>
diff --git a/tests/xsl_iterate/test5.xsl b/tests/xsl_iterate/test5.xsl
new file mode 100644
index 00000000..527a851f
--- /dev/null
+++ b/tests/xsl_iterate/test5.xsl
@@ -0,0 +1,49 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- use with test1_a.xml -->
+
+ <!-- An XSLT stylesheet test, demonstrating use of xsl:iterate
+ with xsl:on-completion. -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:template match="/elem">
+ <result>
+ <xsl:iterate select="a">
+ <xsl:on-completion>
+ <allItemsProcessedWithoutBreak/>
+ </xsl:on-completion>
+ <xsl:choose>
+ <xsl:when test="true()">
+ <item><xsl:value-of select="."/></item>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:break/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:iterate>
+ </result>
+ </xsl:template>
+
+ <!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+</xsl:stylesheet>
diff --git a/tests/xsl_iterate/test6.xsl b/tests/xsl_iterate/test6.xsl
new file mode 100644
index 00000000..abca2daa
--- /dev/null
+++ b/tests/xsl_iterate/test6.xsl
@@ -0,0 +1,49 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- use with test1_a.xml -->
+
+ <!-- An XSLT stylesheet test, demonstrating use of xsl:iterate
+ with xsl:on-completion. -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:template match="/elem">
+ <result>
+ <xsl:iterate select="a">
+ <xsl:on-completion>
+ <allItemsProcessedWithoutBreak/>
+ </xsl:on-completion>
+ <xsl:choose>
+ <xsl:when test="false()">
+ <item><xsl:value-of select="."/></item>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:break/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:iterate>
+ </result>
+ </xsl:template>
+
+ <!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+</xsl:stylesheet>
diff --git a/tests/xsl_iterate/test7.xsl b/tests/xsl_iterate/test7.xsl
new file mode 100644
index 00000000..c0a040e6
--- /dev/null
+++ b/tests/xsl_iterate/test7.xsl
@@ -0,0 +1,43 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- use with test1_a.xml -->
+
+ <!-- An XSLT stylesheet test, that demonstrates, that position()
+ function cannot be called within xsl:on-completion instruction,
+ because within xsl:on-completion 'context item' is absent. -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:template match="/elem">
+ <result>
+ <xsl:iterate select="a">
+ <xsl:on-completion>
+ <status><xsl:value-of select="position()"/></status>
+ </xsl:on-completion>
+ <item><xsl:value-of select="."/></item>
+ </xsl:iterate>
+ </result>
+ </xsl:template>
+
+ <!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+</xsl:stylesheet>
diff --git a/tests/xsl_iterate/test8.xsl b/tests/xsl_iterate/test8.xsl
new file mode 100644
index 00000000..8ba5c11b
--- /dev/null
+++ b/tests/xsl_iterate/test8.xsl
@@ -0,0 +1,43 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- use with test1_a.xml -->
+
+ <!-- An XSLT stylesheet test, that demonstrates, that last()
+ function cannot be called within xsl:on-completion instruction,
+ because within xsl:on-completion 'context item' is absent. -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:template match="/elem">
+ <result>
+ <xsl:iterate select="a">
+ <xsl:on-completion>
+ <status><xsl:value-of select="last()"/></status>
+ </xsl:on-completion>
+ <item><xsl:value-of select="."/></item>
+ </xsl:iterate>
+ </result>
+ </xsl:template>
+
+ <!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+</xsl:stylesheet>
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xalan.apache.org
For additional commands, e-mail: commits-help@xalan.apache.org