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&#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_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