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/10 17:04:41 UTC
[xalan-java] branch xalan-j_xslt3.0 updated: committing implementation of xslt 3.0's xsl:iterate instruction. this is wip. committing related working test case as well, that is part of w3c's xslt 3.0 test suite.
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 6ad4a7b3 committing implementation of xslt 3.0's xsl:iterate instruction. this is wip. committing related working test case as well, that is part of w3c's xslt 3.0 test suite.
6ad4a7b3 is described below
commit 6ad4a7b3c59f1f793a398cee252e484b63e59211
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Sat Jun 10 22:34:19 2023 +0530
committing implementation of xslt 3.0's xsl:iterate instruction. this is wip. committing related working test case as well, that is part of w3c's xslt 3.0 test suite.
---
src/org/apache/xalan/processor/XSLTSchema.java | 35 ++-
src/org/apache/xalan/templates/Constants.java | 13 +-
src/org/apache/xalan/templates/ElemIterate.java | 306 +++++++++++++++++++++
.../xalan/templates/ElemIterateNextIteration.java | 166 +++++++++++
.../xalan/templates/ElemIterateOnCompletion.java | 166 +++++++++++
src/org/apache/xalan/templates/ElemVariable.java | 35 ---
.../xslt/util/XslTransformErrorLocatorHelper.java | 6 +-
tests/org/apache/xalan/xslt3/AllXsl3Tests.java | 3 +-
tests/org/apache/xalan/xslt3/XslIterateTests.java | 61 ++++
.../insn/iterate/gold/iterate-001.out | 20 ++
.../insn/iterate/iterate-001.xsl | 18 ++
.../insn/iterate/iterate001.xml | 89 ++++++
tests/xsl_sequence/test1.xsl | 5 +-
tests/xsl_sequence/test2.xsl | 8 +-
14 files changed, 879 insertions(+), 52 deletions(-)
diff --git a/src/org/apache/xalan/processor/XSLTSchema.java b/src/org/apache/xalan/processor/XSLTSchema.java
index b53b9adc..d1a818a5 100644
--- a/src/org/apache/xalan/processor/XSLTSchema.java
+++ b/src/org/apache/xalan/processor/XSLTSchema.java
@@ -41,6 +41,9 @@ import org.apache.xalan.templates.ElemFallback;
import org.apache.xalan.templates.ElemForEach;
import org.apache.xalan.templates.ElemForEachGroup;
import org.apache.xalan.templates.ElemIf;
+import org.apache.xalan.templates.ElemIterate;
+import org.apache.xalan.templates.ElemIterateNextIteration;
+import org.apache.xalan.templates.ElemIterateOnCompletion;
import org.apache.xalan.templates.ElemLiteralResult;
import org.apache.xalan.templates.ElemMatchingSubstring;
import org.apache.xalan.templates.ElemMessage;
@@ -197,7 +200,7 @@ public class XSLTSchema extends XSLTElementDef
// Required.
- // xsl:value-of, xsl:for-each, xsl:copy-of, xsl:for-each-group, xsl:analyze-string
+ // xsl:value-of, xsl:for-each, xsl:copy-of, xsl:for-each-group, xsl:analyze-string, xsl:iterate
XSLTAttributeDef selectAttrRequired = new XSLTAttributeDef(null,
"select",
XSLTAttributeDef.T_EXPR, true, false, XSLTAttributeDef.ERROR);
@@ -238,7 +241,7 @@ public class XSLTSchema extends XSLTElementDef
XSLTAttributeDef.T_EXPR, false, false, XSLTAttributeDef.ERROR);
// Optional.
- // xsl:variable, xsl:param, xsl:with-param, xsl:attribute
+ // xsl:variable, xsl:param, xsl:with-param, xsl:attribute, xsl:break, xsl:on-completion
XSLTAttributeDef selectAttrOpt = new XSLTAttributeDef(null, "select",
XSLTAttributeDef.T_EXPR, false, false,XSLTAttributeDef.ERROR);
@@ -383,11 +386,11 @@ public class XSLTSchema extends XSLTElementDef
new XSLTAttributeDef(Constants.S_XSLNAMESPACEURL, "*",
XSLTAttributeDef.T_CDATA, false, false,XSLTAttributeDef.WARNING);
- XSLTElementDef[] templateElements = new XSLTElementDef[27];
- XSLTElementDef[] templateElementsAndParams = new XSLTElementDef[28];
- XSLTElementDef[] templateElementsAndSort = new XSLTElementDef[28];
+ XSLTElementDef[] templateElements = new XSLTElementDef[30];
+ XSLTElementDef[] templateElementsAndParams = new XSLTElementDef[31];
+ XSLTElementDef[] templateElementsAndSort = new XSLTElementDef[31];
//exslt
- XSLTElementDef[] exsltFunctionElements = new XSLTElementDef[28];
+ XSLTElementDef[] exsltFunctionElements = new XSLTElementDef[31];
XSLTElementDef[] charTemplateElements = new XSLTElementDef[16];
XSLTElementDef resultElement = new XSLTElementDef(this, null, "*",
@@ -516,6 +519,23 @@ public class XSLTSchema extends XSLTElementDef
new ProcessorTemplateElem(),
ElemNonMatchingSubstring.class /* class object */, true, false, true, 20, true);
+ XSLTElementDef xslIterate = new XSLTElementDef(this, Constants.S_XSLNAMESPACEURL, "iterate",
+ null /*alias */, templateElements,
+ new XSLTAttributeDef[]{ selectAttrRequired }, new ProcessorTemplateElem(),
+ ElemIterate.class /* class object */, true, false, true, 20, true);
+
+ XSLTElementDef xslIterateOnCompletion = new XSLTElementDef(this, Constants.S_XSLNAMESPACEURL, "on-completion",
+ null /*alias */, templateElements,
+ new XSLTAttributeDef[]{ selectAttrOpt }, new ProcessorTemplateElem(),
+ ElemIterateOnCompletion.class /* class object */, true, false,
+ true, 20, true);
+
+ XSLTElementDef xslIterateNextIteration = new XSLTElementDef(this, Constants.S_XSLNAMESPACEURL, "next-iteration",
+ null /*alias */, templateElements,
+ new XSLTAttributeDef[] { }, new ProcessorTemplateElem(),
+ ElemIterateNextIteration.class /* class object */, true, false,
+ true, 20, true);
+
XSLTElementDef xslIf = new XSLTElementDef(this,
Constants.S_XSLNAMESPACEURL,
"if", null /*alias */,
@@ -669,6 +689,9 @@ public class XSLTSchema extends XSLTElementDef
templateElements[i++] = xslAnalyzeString;
templateElements[i++] = xslMatchingSubstring;
templateElements[i++] = xslNonMatchingSubstring;
+ templateElements[i++] = xslIterate;
+ templateElements[i++] = xslIterateOnCompletion;
+ templateElements[i++] = xslIterateNextIteration;
templateElements[i++] = xslValueOf;
templateElements[i++] = xslCopyOf;
templateElements[i++] = xslNumber;
diff --git a/src/org/apache/xalan/templates/Constants.java b/src/org/apache/xalan/templates/Constants.java
index 83692489..d088374e 100644
--- a/src/org/apache/xalan/templates/Constants.java
+++ b/src/org/apache/xalan/templates/Constants.java
@@ -94,9 +94,15 @@ public class Constants extends org.apache.xml.utils.Constants
ELEMNAME_MATCHING_SUBSTRING = 92,
- ELEMNAME_NON_MATCHING_SUBSTRING = 93;
+ ELEMNAME_NON_MATCHING_SUBSTRING = 93,
- // next available number : 94
+ ELEMNAME_ITERATE = 94,
+
+ ELEMNAME_ITERATE_ONCOMPLETION = 95,
+
+ ELEMNAME_ITERATE_NEXTITERATION = 96;
+
+ // next available number : 97
/**
* Literals for XSL element names. Note that there are more
@@ -141,6 +147,9 @@ public class Constants extends org.apache.xml.utils.Constants
ELEMNAME_ANALYZESTRING_STRING = "analyze-string",
ELEMNAME_MATCHINGSUBSTRING_STRING = "matching-substring",
ELEMNAME_NONMATCHINGSUBSTRING_STRING = "non-matching-substring",
+ ELEMNAME_ITERATE_STRING = "iterate",
+ ELEMNAME_ITERATE_ONCOMPLETION_STRING = "on-completion",
+ ELEMNAME_ITERATE_NEXTITERATION_STRING = "next-iteration",
ELEMNAME_IF_STRING = "if",
ELEMNAME_IMPORT_STRING = "import",
ELEMNAME_INCLUDE_STRING = "include",
diff --git a/src/org/apache/xalan/templates/ElemIterate.java b/src/org/apache/xalan/templates/ElemIterate.java
new file mode 100644
index 00000000..a1719f1c
--- /dev/null
+++ b/src/org/apache/xalan/templates/ElemIterate.java
@@ -0,0 +1,306 @@
+/*
+ * 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.
+ */
+package org.apache.xalan.templates;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.transformer.TransformerImpl;
+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.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+
+/**
+ * XSLT 3.0 xsl:iterate element.
+ *
+ <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>
+
+ @author Mukul Gandhi <mu...@apache.org>
+ *
+ * @xsl.usage advanced
+ */
+/*
+ * Implementation of the XSLT 3.0 xsl:iterate instruction.
+ */
+public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
+{
+
+ private static final long serialVersionUID = -2692900882677332482L;
+
+ private static final String OTHER_ELEM = "OTHER_ELEM";
+
+ /**
+ * Construct an element representing xsl:iterate.
+ */
+ public ElemIterate() {}
+
+ /**
+ * The "select" expression.
+ */
+ protected Expression m_selectExpression = null;
+
+ public void setSelect(XPath xpath)
+ {
+ m_selectExpression = xpath.getExpression();
+ }
+
+ /**
+ * Get the "select" attribute.
+ *
+ * @return The XPath expression for the "select" attribute.
+ */
+ public Expression getSelect()
+ {
+ return m_selectExpression;
+ }
+
+ /**
+ * @see ExpressionOwner#setExpression(Expression)
+ */
+ public void setExpression(Expression exp)
+ {
+ exp.exprSetParent(this);
+ m_selectExpression = exp;
+ }
+
+ /**
+ * @see ExpressionOwner#getExpression()
+ */
+ public Expression getExpression()
+ {
+ return m_selectExpression;
+ }
+
+ /**
+ * This function is called after everything else has been recomposed,
+ * and allows the template to set remaining values that may be based
+ * on some other property that depends on recomposition.
+ *
+ * @throws TransformerException
+ */
+ public void compose(StylesheetRoot sroot) throws TransformerException {
+ super.compose(sroot);
+
+ java.util.Vector vnames = sroot.getComposeState().getVariableNames();
+
+ if (m_selectExpression != null) {
+ m_selectExpression.fixupVariables(vnames, sroot.getComposeState().
+ getGlobalsSize());
+ }
+ else {
+ m_selectExpression = getStylesheetRoot().m_selectDefault.
+ getExpression();
+ }
+ }
+
+ /**
+ * This after the template's children have been composed.
+ */
+ public void endCompose(StylesheetRoot sroot) throws TransformerException
+ {
+ super.endCompose(sroot);
+ }
+
+ /**
+ * Get an int constant identifying the type of element.
+ * @see org.apache.xalan.templates.Constants
+ *
+ * @return The token ID for this element
+ */
+ public int getXSLToken()
+ {
+ return Constants.ELEMNAME_ITERATE;
+ }
+
+ /**
+ * Return the node name.
+ *
+ * @return The element's name
+ */
+ public String getNodeName()
+ {
+ return Constants.ELEMNAME_ITERATE_STRING;
+ }
+
+ /**
+ * Execute the xsl:iterate transformation.
+ *
+ * @param transformer non-null reference to the the current transform-time state.
+ *
+ * @throws TransformerException
+ */
+ public void execute(TransformerImpl transformer) throws TransformerException
+ {
+ transformSelectedNodes(transformer);
+ }
+
+ /**
+ * @param transformer non-null reference to the the current transform-time state.
+ *
+ * @throws TransformerException Thrown in a variety of circumstances.
+ *
+ * @xsl.usage advanced
+ */
+ public void transformSelectedNodes(TransformerImpl transformer) throws
+ TransformerException {
+
+ final XPathContext xctxtOriginal = transformer.getXPathContext();
+
+ XPathContext xctxt = transformer.getXPathContext();
+
+ final int sourceNode = xctxt.getCurrentNode();
+
+ validateXslElemIterateChildElementsSequence(xctxt);
+
+ 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);
+
+ int docID = sourceNode & DTMManager.IDENT_DTM_DEFAULT;
+ int child;
+ while ((child = sourceNodes.nextNode()) != DTM.NULL) {
+ currentNodes.setTop(child);
+ currentExpressionNodes.setTop(child);
+
+ if ((child & DTMManager.IDENT_DTM_DEFAULT) != docID)
+ {
+ docID = child & DTMManager.IDENT_DTM_DEFAULT;
+ }
+
+ for (ElemTemplateElement elemTemplate = this.m_firstChild;
+ elemTemplate != null;
+ elemTemplate = elemTemplate.m_nextSibling) {
+ xctxt.setSAXLocator(elemTemplate);
+ transformer.setCurrentElement(elemTemplate);
+ elemTemplate.execute(transformer);
+ }
+ }
+ }
+ 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);
+ }
+
+ /*
+ * The XSLT 3.0 spec specifies constraints, about what should be the order of elements xsl:param,
+ * xsl:on-completion and xsl:next-iteration within the xsl:iterate element. This method ensures
+ * that, these XSLT 3.0 xsl:iterate element constraints are validated during an XSLT stylesheet
+ * transformation.
+ */
+ private void validateXslElemIterateChildElementsSequence(XPathContext xctxt)
+ throws TransformerException {
+
+ List<String> xslElemNamesList = new ArrayList<String>();
+
+ 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 within this "if" condition.
+ 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);
+ }
+ else if (elemTemplate instanceof ElemIterateNextIteration) {
+ xslElemNamesList.add(Constants.ELEMNAME_ITERATE_NEXTITERATION_STRING);
+ }
+ else {
+ xslElemNamesList.add(OTHER_ELEM);
+ }
+ }
+
+ if (xslElemNamesList.indexOf(Constants.ELEMNAME_PARAMVARIABLE_STRING) >
+ xslElemNamesList.indexOf(Constants.ELEMNAME_ITERATE_ONCOMPLETION_STRING)) {
+ throw new TransformerException("XTSE0010 : an xsl:param element must occur before xsl:on-completion "
+ + "element.", xctxt.getSAXLocator());
+ }
+ else if (xslElemNamesList.indexOf(Constants.ELEMNAME_PARAMVARIABLE_STRING) >
+ xslElemNamesList.indexOf(Constants.ELEMNAME_ITERATE_NEXTITERATION_STRING)) {
+ throw new TransformerException("XTSE0010 : an xsl:param element must occur before xsl:next-iteration "
+ + "element.", xctxt.getSAXLocator());
+ }
+ else if (xslElemNamesList.indexOf(Constants.ELEMNAME_PARAMVARIABLE_STRING) >
+ xslElemNamesList.indexOf(OTHER_ELEM)) {
+ throw new TransformerException("XTSE0010 : an xsl:param element must occur before any other element within "
+ + "xsl:iterate element.", xctxt.getSAXLocator());
+ }
+ else if ((xslElemNamesList.indexOf(Constants.ELEMNAME_PARAMVARIABLE_STRING) <
+ xslElemNamesList.indexOf(OTHER_ELEM)) &&
+ (xslElemNamesList.indexOf(OTHER_ELEM) < xslElemNamesList.indexOf(Constants.
+ ELEMNAME_ITERATE_ONCOMPLETION_STRING))) {
+ throw new TransformerException("XTSE0010 : an xsl:on-completion element must be the first child element of xsl:iterate "
+ + "after the xsl:param elements.", xctxt.getSAXLocator());
+ }
+ else if (xslElemNamesList.indexOf(Constants.ELEMNAME_ITERATE_ONCOMPLETION_STRING) >
+ xslElemNamesList.indexOf(Constants.ELEMNAME_ITERATE_NEXTITERATION_STRING)) {
+ throw new TransformerException("XTSE0010 : an xsl:on-completion element must occur before xsl:next-iteration "
+ + "element.", xctxt.getSAXLocator());
+ }
+ }
+
+}
diff --git a/src/org/apache/xalan/templates/ElemIterateNextIteration.java b/src/org/apache/xalan/templates/ElemIterateNextIteration.java
new file mode 100644
index 00000000..56b56b6d
--- /dev/null
+++ b/src/org/apache/xalan/templates/ElemIterateNextIteration.java
@@ -0,0 +1,166 @@
+/*
+ * 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.
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPath;
+
+/**
+ * XSLT 3.0 xsl:next-iteration element.
+ *
+ <xsl:next-iteration>
+ <!-- Content: (xsl:with-param*) -->
+ </xsl:next-iteration>
+
+ @author Mukul Gandhi <mu...@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.
+ */
+public class ElemIterateNextIteration extends ElemTemplateElement implements ExpressionOwner
+{
+
+ private static final long serialVersionUID = -582877657433106548L;
+
+ /**
+ * Construct an element representing xsl:next-iteration.
+ */
+ public ElemIterateNextIteration() {}
+
+ /**
+ * The "select" expression.
+ */
+ protected Expression m_selectExpression = null;
+
+ public void setSelect(XPath xpath)
+ {
+ m_selectExpression = xpath.getExpression();
+ }
+
+ /**
+ * Get the "select" attribute.
+ *
+ * @return The XPath expression for the "select" attribute.
+ */
+ public Expression getSelect()
+ {
+ return m_selectExpression;
+ }
+
+ /**
+ * @see ExpressionOwner#setExpression(Expression)
+ */
+ public void setExpression(Expression exp)
+ {
+ exp.exprSetParent(this);
+ m_selectExpression = exp;
+ }
+
+ /**
+ * @see ExpressionOwner#getExpression()
+ */
+ public Expression getExpression()
+ {
+ return m_selectExpression;
+ }
+
+ /**
+ * This function is called after everything else has been recomposed,
+ * and allows the template to set remaining values that may be based
+ * on some other property that depends on recomposition.
+ *
+ * @throws TransformerException
+ */
+ public void compose(StylesheetRoot sroot) throws TransformerException {
+ super.compose(sroot);
+
+ java.util.Vector vnames = sroot.getComposeState().getVariableNames();
+
+ if (m_selectExpression != null) {
+ m_selectExpression.fixupVariables(vnames, sroot.getComposeState().
+ getGlobalsSize());
+ }
+ else {
+ m_selectExpression = getStylesheetRoot().m_selectDefault.
+ getExpression();
+ }
+ }
+
+ /**
+ * This after the template's children have been composed.
+ */
+ public void endCompose(StylesheetRoot sroot) throws TransformerException
+ {
+ super.endCompose(sroot);
+ }
+
+ /**
+ * Get an int constant identifying the type of element.
+ * @see org.apache.xalan.templates.Constants
+ *
+ * @return The token ID for this element
+ */
+ public int getXSLToken()
+ {
+ return Constants.ELEMNAME_ITERATE_NEXTITERATION;
+ }
+
+ /**
+ * Return the node name.
+ *
+ * @return The element's name
+ */
+ public String getNodeName()
+ {
+ return Constants.ELEMNAME_ITERATE_NEXTITERATION_STRING;
+ }
+
+ /**
+ * Execute the xsl:next-iteration transformation.
+ *
+ * @param transformer non-null reference to the the current transform-time state.
+ *
+ * @throws TransformerException
+ */
+ public void execute(TransformerImpl transformer) throws TransformerException
+ {
+ transformSelectedNodes(transformer);
+ }
+
+ /**
+ * @param transformer non-null reference to the the current transform-time state.
+ *
+ * @throws TransformerException Thrown in a variety of circumstances.
+ *
+ * @xsl.usage advanced
+ */
+ public void transformSelectedNodes(TransformerImpl transformer) throws
+ TransformerException {
+ // TO DO
+ }
+
+}
diff --git a/src/org/apache/xalan/templates/ElemIterateOnCompletion.java b/src/org/apache/xalan/templates/ElemIterateOnCompletion.java
new file mode 100644
index 00000000..f0968533
--- /dev/null
+++ b/src/org/apache/xalan/templates/ElemIterateOnCompletion.java
@@ -0,0 +1,166 @@
+/*
+ * 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.
+ */
+package org.apache.xalan.templates;
+
+import javax.xml.transform.TransformerException;
+
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xpath.Expression;
+import org.apache.xpath.ExpressionOwner;
+import org.apache.xpath.XPath;
+
+/**
+ * XSLT 3.0 xsl:on-completion element.
+ *
+ <xsl:on-completion select? = expression>
+ <!-- Content: sequence-constructor -->
+ </xsl:on-completion>
+
+ @author Mukul Gandhi <mu...@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.
+ */
+public class ElemIterateOnCompletion extends ElemTemplateElement implements ExpressionOwner
+{
+
+ private static final long serialVersionUID = 7800963884351737333L;
+
+ /**
+ * Construct an element representing xsl:on-completion.
+ */
+ public ElemIterateOnCompletion() {}
+
+ /**
+ * The "select" expression.
+ */
+ protected Expression m_selectExpression = null;
+
+ public void setSelect(XPath xpath)
+ {
+ m_selectExpression = xpath.getExpression();
+ }
+
+ /**
+ * Get the "select" attribute.
+ *
+ * @return The XPath expression for the "select" attribute.
+ */
+ public Expression getSelect()
+ {
+ return m_selectExpression;
+ }
+
+ /**
+ * @see ExpressionOwner#setExpression(Expression)
+ */
+ public void setExpression(Expression exp)
+ {
+ exp.exprSetParent(this);
+ m_selectExpression = exp;
+ }
+
+ /**
+ * @see ExpressionOwner#getExpression()
+ */
+ public Expression getExpression()
+ {
+ return m_selectExpression;
+ }
+
+ /**
+ * This function is called after everything else has been recomposed,
+ * and allows the template to set remaining values that may be based
+ * on some other property that depends on recomposition.
+ *
+ * @throws TransformerException
+ */
+ public void compose(StylesheetRoot sroot) throws TransformerException {
+ super.compose(sroot);
+
+ java.util.Vector vnames = sroot.getComposeState().getVariableNames();
+
+ if (m_selectExpression != null) {
+ m_selectExpression.fixupVariables(vnames, sroot.getComposeState().
+ getGlobalsSize());
+ }
+ else {
+ m_selectExpression = getStylesheetRoot().m_selectDefault.
+ getExpression();
+ }
+ }
+
+ /**
+ * This after the template's children have been composed.
+ */
+ public void endCompose(StylesheetRoot sroot) throws TransformerException
+ {
+ super.endCompose(sroot);
+ }
+
+ /**
+ * Get an int constant identifying the type of element.
+ * @see org.apache.xalan.templates.Constants
+ *
+ * @return The token ID for this element
+ */
+ public int getXSLToken()
+ {
+ return Constants.ELEMNAME_ITERATE_ONCOMPLETION;
+ }
+
+ /**
+ * Return the node name.
+ *
+ * @return The element's name
+ */
+ public String getNodeName()
+ {
+ return Constants.ELEMNAME_ITERATE_ONCOMPLETION_STRING;
+ }
+
+ /**
+ * Execute the xsl:on-completion transformation.
+ *
+ * @param transformer non-null reference to the the current transform-time state.
+ *
+ * @throws TransformerException
+ */
+ public void execute(TransformerImpl transformer) throws TransformerException
+ {
+ transformSelectedNodes(transformer);
+ }
+
+ /**
+ * @param transformer non-null reference to the the current transform-time state.
+ *
+ * @throws TransformerException Thrown in a variety of circumstances.
+ *
+ * @xsl.usage advanced
+ */
+ public void transformSelectedNodes(TransformerImpl transformer) throws
+ TransformerException {
+ // TO DO
+ }
+
+}
diff --git a/src/org/apache/xalan/templates/ElemVariable.java b/src/org/apache/xalan/templates/ElemVariable.java
index 97ef6171..b2e3bf13 100644
--- a/src/org/apache/xalan/templates/ElemVariable.java
+++ b/src/org/apache/xalan/templates/ElemVariable.java
@@ -574,40 +574,5 @@ public class ElemVariable extends ElemTemplateElement
}
return super.appendChild(elem);
}
-
- /*private XObject processFuncExtFunction(XPathContext xctxt, Expression expr)
- throws TransformerException, SAXException {
- XObject evalResult = null;
-
- FuncExtFunction funcExtFunction = (FuncExtFunction)expr;
-
- if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(funcExtFunction.
- getNamespace())) {
- if ((Keywords.FUNC_XS_DECIMAL).equals(funcExtFunction.getFunctionName())) {
- ResultSequence argSequence = new ResultSequence();
- for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
- XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
- argSequence.add(new XSDecimal(argVal.str()));
- }
-
- ResultSequence rSeq = (new XSDecimal()).constructor(argSequence);
- evalResult = rSeq.item(0);
- }
- else if ((Keywords.FUNC_BOOLEAN_STRING).equals(funcExtFunction.getFunctionName())) {
- ResultSequence argSequence = new ResultSequence();
- for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
- XObject argVal = (funcExtFunction.getArg(idx)).execute(xctxt);
- Boolean boolVal = Boolean.valueOf("0".equals(argVal.str()) ?
- "false" : "true");
- argSequence.add(new XSBoolean(boolVal));
- }
-
- ResultSequence rSeq = (new XSBoolean()).constructor(argSequence);
- evalResult = rSeq.item(0);
- }
- }
-
- return evalResult;
- } */
}
diff --git a/src/org/apache/xalan/xslt/util/XslTransformErrorLocatorHelper.java b/src/org/apache/xalan/xslt/util/XslTransformErrorLocatorHelper.java
index a9db67f1..8415070a 100644
--- a/src/org/apache/xalan/xslt/util/XslTransformErrorLocatorHelper.java
+++ b/src/org/apache/xalan/xslt/util/XslTransformErrorLocatorHelper.java
@@ -14,11 +14,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.apache.xalan.xslt.util;
/**
- * @version $Id: $
+ *
+ * @author Mukul Gandhi <mu...@apache.org>
+ *
+ * @xsl.usage advanced
*/
public class XslTransformErrorLocatorHelper {
diff --git a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
index 870ffb84..cff17316 100644
--- a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
+++ b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
@@ -46,7 +46,8 @@ import org.junit.runners.Suite.SuiteClasses;
GroupingWithSortTests.class, RtfMigrationTests.class, QuantifiedExprTests.class,
FnUnparsedTextTests.class, FnTokenizeTests.class, FnStringJoinTests.class,
FnAbsTests.class, StringTests.class, XsConstructorFunctions.class,
- FnIndexOfTests.class, SequenceTests.class, RangeExprTests.class })
+ FnIndexOfTests.class, SequenceTests.class, RangeExprTests.class,
+ XslIterateTests.class })
public class AllXsl3Tests {
}
diff --git a/tests/org/apache/xalan/xslt3/XslIterateTests.java b/tests/org/apache/xalan/xslt3/XslIterateTests.java
new file mode 100644
index 00000000..7824cb5f
--- /dev/null
+++ b/tests/org/apache/xalan/xslt3/XslIterateTests.java
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+package org.apache.xalan.xslt3;
+
+import org.apache.xalan.util.XslTransformTestsUtil;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * XSLT 3.0 test cases for the xsl:iterate instruction.
+ *
+ * @author Mukul Gandhi <mu...@apache.org>
+ *
+ * @xsl.usage advanced
+ */
+public class XslIterateTests extends XslTransformTestsUtil {
+
+ private static final String XSL_TRANSFORM_INPUT_DIRPATH = XSLConstants.XSL_TRANSFORM_INPUT_DIRPATH_PREFIX +
+ "w3c_xslt30_testsuite/insn/iterate/";
+
+ private static final String XSL_TRANSFORM_GOLD_DIRPATH = XSLConstants.XSL_TRANSFORM_GOLD_DIRPATH_PREFIX +
+ "w3c_xslt30_testsuite/insn/iterate/gold/";
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ // no op
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception {
+ xmlDocumentBuilderFactory = null;
+ xmlDocumentBuilder = null;
+ xslTransformerFactory = null;
+ }
+
+ @Test
+ public void xslIterateTest1() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "iterate001.xml";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "iterate-001.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "iterate-001.out";
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
+
+}
diff --git a/tests/w3c_xslt30_testsuite/insn/iterate/gold/iterate-001.out b/tests/w3c_xslt30_testsuite/insn/iterate/gold/iterate-001.out
new file mode 100644
index 00000000..a8041c7f
--- /dev/null
+++ b/tests/w3c_xslt30_testsuite/insn/iterate/gold/iterate-001.out
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?><out>
+ <item last="6" position="1">
+ <TITLE>Pride and Prejudice</TITLE>
+ </item>
+ <item last="6" position="2">
+ <TITLE>Wuthering Heights</TITLE>
+ </item>
+ <item last="6" position="3">
+ <TITLE>Tess of the d'Urbervilles</TITLE>
+ </item>
+ <item last="6" position="4">
+ <TITLE>Jude the Obscure</TITLE>
+ </item>
+ <item last="6" position="5">
+ <TITLE>The Big Over Easy</TITLE>
+ </item>
+ <item last="6" position="6">
+ <TITLE>The Eyre Affair</TITLE>
+ </item>
+</out>
diff --git a/tests/w3c_xslt30_testsuite/insn/iterate/iterate-001.xsl b/tests/w3c_xslt30_testsuite/insn/iterate/iterate-001.xsl
new file mode 100644
index 00000000..1ac13cd9
--- /dev/null
+++ b/tests/w3c_xslt30_testsuite/insn/iterate/iterate-001.xsl
@@ -0,0 +1,18 @@
+<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <!-- A primitive test for the XSLT xsl:iterate instruction. Exercises
+ position() and last() functions. -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:template match="/">
+ <out>
+ <xsl:iterate select="//ITEM/TITLE">
+ <item position="{position()}" last="{last()}">
+ <xsl:copy-of select="."/>
+ </item>
+ </xsl:iterate>
+ </out>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tests/w3c_xslt30_testsuite/insn/iterate/iterate001.xml b/tests/w3c_xslt30_testsuite/insn/iterate/iterate001.xml
new file mode 100644
index 00000000..a2e626bb
--- /dev/null
+++ b/tests/w3c_xslt30_testsuite/insn/iterate/iterate001.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0"?>
+<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_sequence/test1.xsl b/tests/xsl_sequence/test1.xsl
index b895e56e..a6459a88 100644
--- a/tests/xsl_sequence/test1.xsl
+++ b/tests/xsl_sequence/test1.xsl
@@ -6,8 +6,9 @@
<!-- use with test1_a.xml -->
- <!-- demonstrating, traversing an XDM sequence comprising of
- XPath 3.1 atomic values, using xsl:for-each instruction. -->
+ <!-- An XSLT stylesheet demonstrating, traversing an XDM sequence
+ comprising of XPath 3.1 atomic values, using xsl:for-each
+ instruction. -->
<xsl:output method="xml" indent="yes"/>
diff --git a/tests/xsl_sequence/test2.xsl b/tests/xsl_sequence/test2.xsl
index 21ba4956..990b7871 100644
--- a/tests/xsl_sequence/test2.xsl
+++ b/tests/xsl_sequence/test2.xsl
@@ -6,10 +6,10 @@
<!-- use with test1_a.xml -->
- <!-- demonstrating, traversing an XDM sequence comprising of
- XPath 3.1 atomic values, using xsl:for-each instruction and
- using specific XDM items depending on their position within
- the sequence. -->
+ <!-- An XSLT stylesheet demonstrating, traversing an XDM
+ sequence comprising of XPath 3.1 atomic values, using
+ xsl:for-each instruction and using specific XDM items
+ depending on their position within the sequence. -->
<xsl:output method="xml" indent="yes"/>
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xalan.apache.org
For additional commands, e-mail: commits-help@xalan.apache.org