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/11 14:58:02 UTC

[xalan-java] branch xalan-j_xslt3.0 updated: improvements to xslt 3.0's xsl:iterate instruction implementation, and implementation of xsl:break instruction for xsl:iterate. committing few related working xslt test cases as well.

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 50f9a628 improvements to xslt 3.0's xsl:iterate instruction implementation, and implementation of xsl:break instruction for xsl:iterate. committing few related working xslt test cases as well.
50f9a628 is described below

commit 50f9a6280af5fc593be6cb9ada1563bfc4ce8f6a
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Sun Jun 11 20:27:29 2023 +0530

    improvements to xslt 3.0's xsl:iterate instruction implementation, and implementation of xsl:break instruction for xsl:iterate. committing few related working xslt test cases as well.
---
 src/org/apache/xalan/processor/XSLTSchema.java     |  14 +-
 src/org/apache/xalan/templates/Constants.java      |   7 +-
 src/org/apache/xalan/templates/ElemIterate.java    |  69 ++++---
 .../apache/xalan/templates/ElemIterateBreak.java   | 207 +++++++++++++++++++++
 .../xalan/templates/ElemTemplateElement.java       |  39 ++--
 src/org/apache/xalan/templates/ElemUnknown.java    |  17 +-
 .../xslt/util/XslTransformErrorLocatorHelper.java  |   5 +
 tests/org/apache/xalan/xslt3/AllXsl3Tests.java     |   2 +-
 ...rateTests.java => W3c_xslt30_IterateTests.java} |   2 +-
 tests/org/apache/xalan/xslt3/XslIterateTests.java  |  30 ++-
 tests/xsl_iterate/gold/test1.out                   |   7 +
 tests/xsl_iterate/gold/test2.out                   |   8 +
 tests/xsl_iterate/gold/test3.out                   |  32 ++++
 tests/xsl_iterate/test1.xsl                        |  47 +++++
 tests/xsl_iterate/test1_a.xml                      |  10 +
 tests/xsl_iterate/test1_b.xml                      |  43 +++++
 tests/xsl_iterate/test2.xsl                        |  48 +++++
 tests/xsl_iterate/test3.xsl                        |  66 +++++++
 18 files changed, 589 insertions(+), 64 deletions(-)

diff --git a/src/org/apache/xalan/processor/XSLTSchema.java b/src/org/apache/xalan/processor/XSLTSchema.java
index d1a818a5..37d76749 100644
--- a/src/org/apache/xalan/processor/XSLTSchema.java
+++ b/src/org/apache/xalan/processor/XSLTSchema.java
@@ -42,6 +42,7 @@ 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.ElemIterateBreak;
 import org.apache.xalan.templates.ElemIterateNextIteration;
 import org.apache.xalan.templates.ElemIterateOnCompletion;
 import org.apache.xalan.templates.ElemLiteralResult;
@@ -386,11 +387,11 @@ public class XSLTSchema extends XSLTElementDef
       new XSLTAttributeDef(Constants.S_XSLNAMESPACEURL, "*",
                            XSLTAttributeDef.T_CDATA, false, false,XSLTAttributeDef.WARNING);
                            
-    XSLTElementDef[] templateElements = new XSLTElementDef[30];
-    XSLTElementDef[] templateElementsAndParams = new XSLTElementDef[31];
-    XSLTElementDef[] templateElementsAndSort = new XSLTElementDef[31];
+    XSLTElementDef[] templateElements = new XSLTElementDef[31];
+    XSLTElementDef[] templateElementsAndParams = new XSLTElementDef[32];
+    XSLTElementDef[] templateElementsAndSort = new XSLTElementDef[32];
     //exslt
-    XSLTElementDef[] exsltFunctionElements = new XSLTElementDef[31];
+    XSLTElementDef[] exsltFunctionElements = new XSLTElementDef[32];
     
     XSLTElementDef[] charTemplateElements = new XSLTElementDef[16];
     XSLTElementDef resultElement = new XSLTElementDef(this, null, "*",
@@ -536,6 +537,10 @@ public class XSLTSchema extends XSLTElementDef
                                                                 ElemIterateNextIteration.class /* class object */, true, false, 
                                                                 true, 20, true);
     
+    XSLTElementDef xslIterateBreak = new XSLTElementDef(this, Constants.S_XSLNAMESPACEURL, "break", null /*alias */, templateElements,
+                                                        new XSLTAttributeDef[]{ selectAttrOpt }, new ProcessorTemplateElem(), 
+                                                        ElemIterateBreak.class /* class object */, true, false, true, 20, true);
+    
     XSLTElementDef xslIf = new XSLTElementDef(this,
                                               Constants.S_XSLNAMESPACEURL,
                                               "if", null /*alias */,
@@ -690,6 +695,7 @@ public class XSLTSchema extends XSLTElementDef
     templateElements[i++] = xslMatchingSubstring;
     templateElements[i++] = xslNonMatchingSubstring;
     templateElements[i++] = xslIterate;
+    templateElements[i++] = xslIterateBreak;
     templateElements[i++] = xslIterateOnCompletion;
     templateElements[i++] = xslIterateNextIteration;
     templateElements[i++] = xslValueOf;
diff --git a/src/org/apache/xalan/templates/Constants.java b/src/org/apache/xalan/templates/Constants.java
index d088374e..47ed4261 100644
--- a/src/org/apache/xalan/templates/Constants.java
+++ b/src/org/apache/xalan/templates/Constants.java
@@ -100,9 +100,11 @@ public class Constants extends org.apache.xml.utils.Constants
   
   ELEMNAME_ITERATE_ONCOMPLETION = 95,
   
-  ELEMNAME_ITERATE_NEXTITERATION = 96;
+  ELEMNAME_ITERATE_NEXTITERATION = 96,
   
-  // next available number : 97
+  ELEMNAME_ITERATE_BREAK = 97;
+  
+  // next available number : 98
 
   /**
    * Literals for XSL element names. Note that there are more
@@ -150,6 +152,7 @@ public class Constants extends org.apache.xml.utils.Constants
       ELEMNAME_ITERATE_STRING = "iterate",
       ELEMNAME_ITERATE_ONCOMPLETION_STRING = "on-completion",
       ELEMNAME_ITERATE_NEXTITERATION_STRING = "next-iteration",
+      ELEMNAME_ITERATE_BREAK_STRING = "break",
       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
index a1719f1c..cea1e7d3 100644
--- a/src/org/apache/xalan/templates/ElemIterate.java
+++ b/src/org/apache/xalan/templates/ElemIterate.java
@@ -23,6 +23,7 @@ import java.util.List;
 import javax.xml.transform.TransformerException;
 
 import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xalan.xslt.util.XslTransformErrorLocatorHelper;
 import org.apache.xml.dtm.DTM;
 import org.apache.xml.dtm.DTMIterator;
 import org.apache.xml.dtm.DTMManager;
@@ -217,11 +218,21 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
                    for (ElemTemplateElement elemTemplate = this.m_firstChild; 
                                                           elemTemplate != null; 
                                                           elemTemplate = elemTemplate.m_nextSibling) {
-                       xctxt.setSAXLocator(elemTemplate);
-                       transformer.setCurrentElement(elemTemplate);
-                       elemTemplate.execute(transformer);
-                   }	 	
-                }
+                       if (!((XslTransformErrorLocatorHelper.isXslIterateBreakEvaluated).booleanValue())) {
+                          xctxt.setSAXLocator(elemTemplate);
+                          transformer.setCurrentElement(elemTemplate);
+                          elemTemplate.execute(transformer);
+                       }
+                       else {
+                          break;    
+                       }
+                   }
+                   
+                   if ((XslTransformErrorLocatorHelper.isXslIterateBreakEvaluated).booleanValue()) {
+                       XslTransformErrorLocatorHelper.isXslIterateBreakEvaluated = Boolean.FALSE;
+                       break;   
+                   }
+               }
            }
            finally {
               xctxt.popSAXLocator();
@@ -238,10 +249,10 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
       }
       
        /*
-        * 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.  
+        * The XSLT 3.0 spec specifies constraints, about what should be the order of XSLT elements 
+        * xsl:param, xsl:on-completion and xsl:next-iteration within the xsl:iterate element. This 
+        * method ensures that, these XSLT xsl:iterate element constraints are validated during 
+        * an XSLT document transformation.  
         */
       private void validateXslElemIterateChildElementsSequence(XPathContext xctxt) 
                                                                        throws TransformerException {
@@ -274,32 +285,38 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
               }
           }
           
-          if (xslElemNamesList.indexOf(Constants.ELEMNAME_PARAMVARIABLE_STRING) > 
-                                                    xslElemNamesList.indexOf(Constants.ELEMNAME_ITERATE_ONCOMPLETION_STRING)) {
+          // 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 
+          // 'xslElemNamesList', its index is returned as -1.
+          int paramIdx = xslElemNamesList.indexOf(Constants.ELEMNAME_PARAMVARIABLE_STRING);
+          int onCompletionIdx = xslElemNamesList.indexOf(Constants.ELEMNAME_ITERATE_ONCOMPLETION_STRING);
+          int nextIterationIdx = xslElemNamesList.indexOf(Constants.ELEMNAME_ITERATE_NEXTITERATION_STRING);
+          int otherElemIdx = xslElemNamesList.indexOf(OTHER_ELEM);
+          
+          if ((paramIdx != -1) && (onCompletionIdx != -1) && (paramIdx > onCompletionIdx)) {
               throw new TransformerException("XTSE0010 : an xsl:param element must occur before xsl:on-completion "
-                                                                                                         + "element.", xctxt.getSAXLocator());    
+                                                                                            + "element.", xctxt.getSAXLocator());    
           }          
-          else if (xslElemNamesList.indexOf(Constants.ELEMNAME_PARAMVARIABLE_STRING) > 
-                                                    xslElemNamesList.indexOf(Constants.ELEMNAME_ITERATE_NEXTITERATION_STRING)) {
+          else if ((paramIdx != -1) && (nextIterationIdx != -1) && (paramIdx > nextIterationIdx)) {
               throw new TransformerException("XTSE0010 : an xsl:param element must occur before xsl:next-iteration "
-                                                                                                         + "element.", xctxt.getSAXLocator());
+                                                                                            + "element.", xctxt.getSAXLocator());
           }
-          else if (xslElemNamesList.indexOf(Constants.ELEMNAME_PARAMVARIABLE_STRING) > 
-                                                                         xslElemNamesList.indexOf(OTHER_ELEM)) {
+          else if ((paramIdx != -1) && (otherElemIdx != -1) && (paramIdx > otherElemIdx)) {
               throw new TransformerException("XTSE0010 : an xsl:param element must occur before any other element within "
-                                                                                                  + "xsl:iterate element.", xctxt.getSAXLocator());
+                                                                                     + "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))) {
+          else if ((paramIdx != -1) && (otherElemIdx != -1) && (onCompletionIdx != -1) && (paramIdx < otherElemIdx) && 
+                                                                                                 (otherElemIdx < onCompletionIdx)) {
               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());
+                                                                                 + "after the xsl:param elements.", xctxt.getSAXLocator());
           }
-          else if (xslElemNamesList.indexOf(Constants.ELEMNAME_ITERATE_ONCOMPLETION_STRING) > 
-                                                                      xslElemNamesList.indexOf(Constants.ELEMNAME_ITERATE_NEXTITERATION_STRING)) {
+          else if ((onCompletionIdx != -1) && (nextIterationIdx != -1) && (onCompletionIdx > nextIterationIdx)) {
               throw new TransformerException("XTSE0010 : an xsl:on-completion element must occur before xsl:next-iteration "
-                                                                                                              + "element.", xctxt.getSAXLocator());
+                                                                                                   + "element.", xctxt.getSAXLocator());
+          }
+          else if ((nextIterationIdx != -1) && (nextIterationIdx != (xslElemNamesList.size() - 1))) {
+              throw new TransformerException("XTSE3120 : an xsl:next-iteration element when present, must be the last instruction within "
+                                                                                         + "an xsl:iterate loop.", xctxt.getSAXLocator());
           }
       }
       
diff --git a/src/org/apache/xalan/templates/ElemIterateBreak.java b/src/org/apache/xalan/templates/ElemIterateBreak.java
new file mode 100644
index 00000000..0c650150
--- /dev/null
+++ b/src/org/apache/xalan/templates/ElemIterateBreak.java
@@ -0,0 +1,207 @@
+/*
+ * 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.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;
+
+/**
+ * XSLT 3.0 xsl:break element.
+ * 
+   <xsl:break select? = expression>
+      <!-- Content: sequence-constructor -->
+   </xsl:break>
+         
+   @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+/*
+ * Implementation of the XSLT 3.0 xsl:break instruction.
+ * 
+ * The XSLT xsl:break element is intended to be used, within xsl:iterate element.
+ */
+public class ElemIterateBreak extends ElemTemplateElement implements ExpressionOwner
+{
+
+     private static final long serialVersionUID = -7523525132174243558L;
+
+     /**
+      * Construct an element representing xsl:break.
+      */
+     public ElemIterateBreak() {}
+     
+     private String xpathSelectPatternStr;
+
+     /**
+      * The "select" expression.
+      */
+     protected Expression m_selectExpression = null;
+
+     public void setSelect(XPath xpath)
+     {
+         m_selectExpression = xpath.getExpression();
+         xpathSelectPatternStr = xpath.getPatternString();
+     }
+
+     /**
+      * 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_BREAK;
+       }
+
+       /**
+         * Return the node name.
+         *
+         * @return The element's name
+       */
+       public String getNodeName()
+       {
+           return Constants.ELEMNAME_ITERATE_BREAK_STRING;
+       }
+
+       /**
+        * Execute the xsl:break transformation.
+        *
+        * @param transformer non-null reference to the the current transform-time state.
+        *
+        * @throws TransformerException
+       */
+       public void execute(TransformerImpl transformer) throws TransformerException
+       {
+           if (this.m_nextSibling != null) {
+              XPathContext xpathContext = transformer.getXPathContext();
+              throw new TransformerException("XTSE3120 : an xsl:break instruction must not have any other "
+                                                                          + "stylesheet element as its sibling.", 
+                                                                                           xpathContext.getSAXLocator());    
+           }
+           else {
+              XslTransformErrorLocatorHelper.isXslIterateBreakEvaluated = Boolean.TRUE;
+              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 {
+           XPathContext xctxt = transformer.getXPathContext();
+           
+           if ((xpathSelectPatternStr != null) && (this.m_firstChild != null)) {
+              throw new TransformerException("XTSE3125 : an xsl:break element with a 'select' attribute "
+                                                                                 + "must be empty.", xctxt.getSAXLocator());          
+           }
+           else {               
+              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);
+                  } 
+              }
+           }
+       }
+      
+}
diff --git a/src/org/apache/xalan/templates/ElemTemplateElement.java b/src/org/apache/xalan/templates/ElemTemplateElement.java
index 5edccbc9..9282501b 100644
--- a/src/org/apache/xalan/templates/ElemTemplateElement.java
+++ b/src/org/apache/xalan/templates/ElemTemplateElement.java
@@ -1657,29 +1657,28 @@ public class ElemTemplateElement extends UnImplNode
   {
   	callChildVisitors(visitor, true);
   }
+  
+  /**
+   * @see PrefixResolver#handlesNullPrefixes()
+   */
+  public boolean handlesNullPrefixes() {
+      return false;
+  }
 
+  public Object getGroupingKey() {
+      return fGroupingKey;
+  }
 
-	/**
-	 * @see PrefixResolver#handlesNullPrefixes()
-	 */
-	public boolean handlesNullPrefixes() {
-		return false;
-	}
-
-    public Object getGroupingKey() {
-        return fGroupingKey;
-    }
-
-    public void setGroupingKey(Object groupingKey) {
-        this.fGroupingKey = groupingKey;
-    }
+  public void setGroupingKey(Object groupingKey) {
+      this.fGroupingKey = groupingKey;
+  }
 
-    public List<Integer> getGroupNodesDtmHandles() {
-        return fGroupNodesDtmHandles;
-    }
+  public List<Integer> getGroupNodesDtmHandles() {
+      return fGroupNodesDtmHandles;
+  }
 
-    public void setGroupNodesDtmHandles(List<Integer> groupNodesDtmHandles) {
-        this.fGroupNodesDtmHandles = groupNodesDtmHandles;
-    }
+  public void setGroupNodesDtmHandles(List<Integer> groupNodesDtmHandles) {
+      this.fGroupNodesDtmHandles = groupNodesDtmHandles;
+  }
 
 }
diff --git a/src/org/apache/xalan/templates/ElemUnknown.java b/src/org/apache/xalan/templates/ElemUnknown.java
index 7e3ccdc6..e7d38694 100644
--- a/src/org/apache/xalan/templates/ElemUnknown.java
+++ b/src/org/apache/xalan/templates/ElemUnknown.java
@@ -21,12 +21,10 @@
 package org.apache.xalan.templates;
 
 import javax.xml.transform.TransformerException;
-import org.apache.xalan.res.XSLMessages;
-import org.apache.xalan.res.XSLTErrorResources;
+
 import org.apache.xalan.transformer.TransformerImpl;
 import org.apache.xpath.XPathContext;
 
-
 /**
  * Implement an unknown element
  * @xsl.usage advanced
@@ -115,7 +113,16 @@ public class ElemUnknown extends ElemLiteralResult
 		if (hasFallbackChildren()) {
 			executeFallbacks(transformer);
 		} else {
-			// do nothing
+		    // revisit.
+		    // there may be a better way to handle this condition
+		    String elemNsUri = getNamespace();		    		    
+		    if ((Constants.S_XSLNAMESPACEURL).equals(elemNsUri) && 
+		                                         !(Constants.ELEMNAME_PARAMVARIABLE_STRING).equals(getLocalName())) {
+		       XPathContext xctxt = transformer.getXPathContext();
+		       throw new TransformerException("XTSE0010 : an instruction " + getNodeName() + " is "
+		                                                          + "not known to the XSLT processor.", 
+		                                                                                       xctxt.getSAXLocator());
+		    }
 		}
 		
 	} catch (TransformerException e) {
@@ -123,6 +130,6 @@ public class ElemUnknown extends ElemLiteralResult
 	}
     if (transformer.getDebug())
 		transformer.getTraceManager().fireTraceEndEvent(this);
-  }
+    }
 
 }
diff --git a/src/org/apache/xalan/xslt/util/XslTransformErrorLocatorHelper.java b/src/org/apache/xalan/xslt/util/XslTransformErrorLocatorHelper.java
index 8415070a..06ce48d5 100644
--- a/src/org/apache/xalan/xslt/util/XslTransformErrorLocatorHelper.java
+++ b/src/org/apache/xalan/xslt/util/XslTransformErrorLocatorHelper.java
@@ -22,8 +22,13 @@ package org.apache.xalan.xslt.util;
  * 
  * @xsl.usage advanced
  */
+/*
+ * This class, stores few XSLT document transformation wide variables.
+ */
 public class XslTransformErrorLocatorHelper {
     
     public static String systemId;
+    
+    public static Boolean isXslIterateBreakEvaluated = Boolean.FALSE;
 
 }
diff --git a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
index cff17316..7b9ccd26 100644
--- a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
+++ b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
@@ -47,7 +47,7 @@ import org.junit.runners.Suite.SuiteClasses;
                 FnUnparsedTextTests.class, FnTokenizeTests.class, FnStringJoinTests.class,
                 FnAbsTests.class, StringTests.class, XsConstructorFunctions.class, 
                 FnIndexOfTests.class, SequenceTests.class, RangeExprTests.class, 
-                XslIterateTests.class })
+                W3c_xslt30_IterateTests.class, XslIterateTests.class })
 public class AllXsl3Tests {
 
 }
diff --git a/tests/org/apache/xalan/xslt3/XslIterateTests.java b/tests/org/apache/xalan/xslt3/W3c_xslt30_IterateTests.java
similarity index 97%
copy from tests/org/apache/xalan/xslt3/XslIterateTests.java
copy to tests/org/apache/xalan/xslt3/W3c_xslt30_IterateTests.java
index 7824cb5f..60c6baab 100644
--- a/tests/org/apache/xalan/xslt3/XslIterateTests.java
+++ b/tests/org/apache/xalan/xslt3/W3c_xslt30_IterateTests.java
@@ -28,7 +28,7 @@ import org.junit.Test;
  * 
  * @xsl.usage advanced
  */
-public class XslIterateTests extends XslTransformTestsUtil {
+public class W3c_xslt30_IterateTests extends XslTransformTestsUtil {
     
     private static final String XSL_TRANSFORM_INPUT_DIRPATH = XSLConstants.XSL_TRANSFORM_INPUT_DIRPATH_PREFIX + 
                                                                                                  "w3c_xslt30_testsuite/insn/iterate/";
diff --git a/tests/org/apache/xalan/xslt3/XslIterateTests.java b/tests/org/apache/xalan/xslt3/XslIterateTests.java
index 7824cb5f..573fa976 100644
--- a/tests/org/apache/xalan/xslt3/XslIterateTests.java
+++ b/tests/org/apache/xalan/xslt3/XslIterateTests.java
@@ -31,10 +31,10 @@ import org.junit.Test;
 public class XslIterateTests extends XslTransformTestsUtil {
     
     private static final String XSL_TRANSFORM_INPUT_DIRPATH = XSLConstants.XSL_TRANSFORM_INPUT_DIRPATH_PREFIX + 
-                                                                                                 "w3c_xslt30_testsuite/insn/iterate/";
+                                                                                                          "xsl_iterate/";
     
     private static final String XSL_TRANSFORM_GOLD_DIRPATH = XSLConstants.XSL_TRANSFORM_GOLD_DIRPATH_PREFIX + 
-                                                                                                 "w3c_xslt30_testsuite/insn/iterate/gold/";
+                                                                                                          "xsl_iterate/gold/";
 
     @BeforeClass
     public static void setUpBeforeClass() throws Exception {
@@ -50,10 +50,30 @@ public class XslIterateTests extends XslTransformTestsUtil {
 
     @Test
     public void xslIterateTest1() {
-        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "iterate001.xml"; 
-        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "iterate-001.xsl";
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl";
         
-        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "iterate-001.out";                
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test1.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslIterateTest2() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test2.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslIterateTest3() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_b.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test3.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test3.out";                
         
         runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
     }
diff --git a/tests/xsl_iterate/gold/test1.out b/tests/xsl_iterate/gold/test1.out
new file mode 100644
index 00000000..b4587266
--- /dev/null
+++ b/tests/xsl_iterate/gold/test1.out
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <a>hello1</a>
+  <a>hello2</a>
+  <a>hello3</a>
+  <a>hello4</a>
+  <a>hello5</a>
+</result>
diff --git a/tests/xsl_iterate/gold/test2.out b/tests/xsl_iterate/gold/test2.out
new file mode 100644
index 00000000..6367946f
--- /dev/null
+++ b/tests/xsl_iterate/gold/test2.out
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <a>hello1</a>
+  <a>hello2</a>
+  <a>hello3</a>
+  <a>hello4</a>
+  <a>hello5</a>
+  <exited_from_loop itemsProcessed="5"/>
+</result>
diff --git a/tests/xsl_iterate/gold/test3.out b/tests/xsl_iterate/gold/test3.out
new file mode 100644
index 00000000..3f9618aa
--- /dev/null
+++ b/tests/xsl_iterate/gold/test3.out
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <out>
+    <p>a</p>
+    <exit of="6" at="2"/>
+  </out>
+  <out>
+    <p>f</p>
+    <p>g</p>
+    <exit of="6" at="3"/>
+  </out>
+  <out>
+    <p>k</p>
+    <p>l</p>
+    <p>m</p>
+    <exit of="6" at="4"/>
+  </out>
+  <out>
+    <p>p</p>
+    <p>q</p>
+    <p>r</p>
+    <p>s</p>
+    <exit of="6" at="5"/>
+  </out>
+  <out>
+    <p>u</p>
+    <p>v</p>
+    <p>w</p>
+    <p>x</p>
+    <p>y</p>
+    <exit of="6" at="6"/>
+  </out>
+</result>
diff --git a/tests/xsl_iterate/test1.xsl b/tests/xsl_iterate/test1.xsl
new file mode 100644
index 00000000..7f980c5e
--- /dev/null
+++ b/tests/xsl_iterate/test1.xsl
@@ -0,0 +1,47 @@
+<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 case, that uses xsl:iterate, 
+       with xsl:break to exit from xsl:iterate loop when a 
+       particular condition is evaluated as true.  -->                 
+  
+  <xsl:output method="xml" indent="yes"/>
+
+  <xsl:template match="/elem">
+    <result>
+      <xsl:iterate select="a">
+        <xsl:choose>
+          <xsl:when test=". = 'hello6'">
+            <xsl:break/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:copy-of select="."/>
+          </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/test1_a.xml b/tests/xsl_iterate/test1_a.xml
new file mode 100644
index 00000000..777b067d
--- /dev/null
+++ b/tests/xsl_iterate/test1_a.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<elem>
+   <a>hello1</a>
+   <a>hello2</a>
+   <a>hello3</a>
+   <a>hello4</a>
+   <a>hello5</a>
+   <a>hello6</a>
+   <a>hello7</a>
+</elem>
\ No newline at end of file
diff --git a/tests/xsl_iterate/test1_b.xml b/tests/xsl_iterate/test1_b.xml
new file mode 100644
index 00000000..41c0b15c
--- /dev/null
+++ b/tests/xsl_iterate/test1_b.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<elem>
+  <page>
+    <p>a</p>
+    <h3>info1</h3>
+    <p>b</p>
+    <p>c</p>
+    <p>d</p>
+    <p>e</p>
+  </page>
+  <page>
+    <p>f</p>    
+    <p>g</p>
+    <h3>info1</h3>
+    <p>h</p>
+    <p>i</p>    
+    <p>j</p>
+  </page>
+  <page>
+    <p>k</p>
+    <p>l</p>
+    <p>m</p>
+    <h3>info1</h3>
+    <p>n</p>
+    <p>o</p>
+  </page>
+  <page>
+    <p>p</p>
+    <p>q</p>
+    <p>r</p>
+    <p>s</p>
+    <h3>info1</h3>
+    <p>t</p>
+  </page>
+  <page>
+    <p>u</p>
+    <p>v</p>
+    <p>w</p>
+    <p>x</p>
+    <p>y</p>
+    <h3>info1</h3>
+  </page>
+</elem>
\ No newline at end of file
diff --git a/tests/xsl_iterate/test2.xsl b/tests/xsl_iterate/test2.xsl
new file mode 100644
index 00000000..104821a9
--- /dev/null
+++ b/tests/xsl_iterate/test2.xsl
@@ -0,0 +1,48 @@
+<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 case, that uses xsl:iterate, 
+       with xsl:break to exit from xsl:iterate loop when a 
+       particular condition is evaluated as true.  --> 
+  
+  <xsl:output method="xml" indent="yes"/>
+
+  <xsl:template match="/elem">
+    <result>
+      <xsl:iterate select="a">
+        <xsl:choose>
+          <xsl:when test=". = 'hello6'">
+            <exited_from_loop itemsProcessed="{position()-1}"/>
+            <xsl:break/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:copy-of select="."/>
+          </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/test3.xsl b/tests/xsl_iterate/test3.xsl
new file mode 100644
index 00000000..543466bc
--- /dev/null
+++ b/tests/xsl_iterate/test3.xsl
@@ -0,0 +1,66 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="3.0">
+                
+  <!-- Author: mukulg@apache.org -->
+   
+  <!-- use with test1_b.xml -->
+  
+  <!-- An XSLT stylesheet test case, that uses xsl:iterate
+       instruction multiple times depending on how many XML 
+       input elements are there in sequence, for a given 
+       XML document input structure. For each application 
+       of xsl:iterate instruction, there's a xsl:break instruction 
+       to exit from the current xsl:iterate loop at specific 
+       conditions.
+       
+       This XSLT stylesheet, has been adapted from one of W3C
+       XSLT 3.0 test cases. -->                
+                
+  <xsl:output method="xml" indent="yes"/>                
+
+  <xsl:template match="/">
+     <result>
+        <xsl:apply-templates select="//page"/>
+     </result>
+  </xsl:template>
+
+  <xsl:template match="page">
+     <out>
+        <xsl:iterate select="*">
+           <xsl:choose>
+              <xsl:when test="self::h3">
+                <xsl:break>
+                  <exit at="{position()}" of="{last()}"/>
+                </xsl:break>
+              </xsl:when>
+              <xsl:otherwise>
+                 <xsl:apply-templates select="self::p"/>
+              </xsl:otherwise>
+           </xsl:choose>
+        </xsl:iterate>
+     </out>
+  </xsl:template>
+
+  <xsl:template match="p">
+     <xsl:copy-of select="."/>
+  </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