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 2024/05/31 10:24:55 UTC

(xalan-java) branch xalan-j_xslt3.0 updated: xalanj xsl3 branch changes : committing implementation of xpath3.1 array functions insert-before, head, tail, reverse. refactoring of few codebase files. adding various new working relevant 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 e9029d32 xalanj xsl3 branch changes : committing implementation of xpath3.1 array functions insert-before, head, tail, reverse. refactoring of few codebase files. adding various new working relevant test cases as well.
e9029d32 is described below

commit e9029d32935adec84275ff600e806928bdc2ad00
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Fri May 31 15:54:42 2024 +0530

    xalanj xsl3 branch changes : committing implementation of xpath3.1 array functions insert-before, head, tail, reverse. refactoring of few codebase files. adding various new working relevant test cases as well.
---
 src/org/apache/xpath/compiler/FunctionTable.java   |  12 ++
 src/org/apache/xpath/compiler/XPathParserImpl.java | 183 ++++++++++++++-------
 .../xpath/composite/SequenceTypeSupport.java       |  22 ++-
 src/org/apache/xpath/functions/FuncForEach.java    |   8 +-
 .../xpath/functions/array/FuncArrayHead.java       |  74 +++++++++
 .../functions/array/FuncArrayInsertBefore.java     | 136 +++++++++++++++
 .../xpath/functions/array/FuncArrayReverse.java    |  76 +++++++++
 .../xpath/functions/array/FuncArrayTail.java       |  82 +++++++++
 .../xalan/xpath3/InlineFunctionItemExprTests.java  |   3 +-
 tests/org/apache/xalan/xpath3/XPathArrayTests.java |  40 +++++
 tests/org/apache/xalan/xpath3/XPathMapTests.java   |  40 +++++
 tests/xpath_array/gold/test10.out                  |   4 +
 tests/xpath_array/gold/test11.out                  |   4 +
 tests/xpath_array/gold/test12.out                  |   3 +
 tests/xpath_array/gold/test9.out                   |   5 +
 tests/xpath_array/test10.xsl                       |  55 +++++++
 tests/xpath_array/test11.xsl                       |  51 ++++++
 tests/xpath_array/test12.xsl                       |  43 +++++
 tests/xpath_array/test9.xsl                        |  54 ++++++
 tests/xpath_maps/gold/test17.out                   |   5 +
 tests/xpath_maps/gold/test18.out                   |   5 +
 tests/xpath_maps/gold/test19.out                   |   5 +
 tests/xpath_maps/gold/test20.out                   |   5 +
 tests/xpath_maps/test15.xsl                        |   6 +-
 tests/xpath_maps/test16.xsl                        |   6 +-
 tests/xpath_maps/{test16.xsl => test17.xsl}        |  36 +---
 tests/xpath_maps/{test15.xsl => test18.xsl}        |  36 +---
 tests/xpath_maps/{test15.xsl => test19.xsl}        |  14 +-
 tests/xpath_maps/{test16.xsl => test20.xsl}        |  14 +-
 29 files changed, 888 insertions(+), 139 deletions(-)

diff --git a/src/org/apache/xpath/compiler/FunctionTable.java b/src/org/apache/xpath/compiler/FunctionTable.java
index 0161cb64..5bc394f8 100644
--- a/src/org/apache/xpath/compiler/FunctionTable.java
+++ b/src/org/apache/xpath/compiler/FunctionTable.java
@@ -805,6 +805,10 @@ public class FunctionTable
     m_functions[FUNC_ARRAY_APPEND] = org.apache.xpath.functions.array.FuncArrayAppend.class;
     m_functions[FUNC_ARRAY_SUBARRAY] = org.apache.xpath.functions.array.FuncSubarray.class;
     m_functions[FUNC_ARRAY_REMOVE] = org.apache.xpath.functions.array.FuncArrayRemove.class;
+    m_functions[FUNC_ARRAY_INSERT_BEFORE] = org.apache.xpath.functions.array.FuncArrayInsertBefore.class;
+    m_functions[FUNC_ARRAY_HEAD] = org.apache.xpath.functions.array.FuncArrayHead.class;
+    m_functions[FUNC_ARRAY_TAIL] = org.apache.xpath.functions.array.FuncArrayTail.class;
+    m_functions[FUNC_ARRAY_REVERSE] = org.apache.xpath.functions.array.FuncArrayReverse.class;
     
     // XPath 3.1 built-in functions configurations for the map 
     // functions namespace http://www.w3.org/2005/xpath-functions/map    
@@ -1108,6 +1112,14 @@ public class FunctionTable
                           new Integer(FunctionTable.FUNC_ARRAY_SUBARRAY));
          m_functionID.put(Keywords.FUNC_ARRAY_REMOVE,
                           new Integer(FunctionTable.FUNC_ARRAY_REMOVE));
+         m_functionID.put(Keywords.FUNC_ARRAY_INSERT_BEFORE,
+                          new Integer(FunctionTable.FUNC_ARRAY_INSERT_BEFORE));
+         m_functionID.put(Keywords.FUNC_ARRAY_HEAD,
+                          new Integer(FunctionTable.FUNC_ARRAY_HEAD));
+         m_functionID.put(Keywords.FUNC_ARRAY_TAIL,
+                          new Integer(FunctionTable.FUNC_ARRAY_TAIL));
+         m_functionID.put(Keywords.FUNC_ARRAY_REVERSE,
+                          new Integer(FunctionTable.FUNC_ARRAY_REVERSE));
          
          m_functionID.put(Keywords.FUNC_NAME_STRING,
                           new Integer(FunctionTable.FUNC_NAME));
diff --git a/src/org/apache/xpath/compiler/XPathParserImpl.java b/src/org/apache/xpath/compiler/XPathParserImpl.java
index 427f9b93..74575656 100644
--- a/src/org/apache/xpath/compiler/XPathParserImpl.java
+++ b/src/org/apache/xpath/compiler/XPathParserImpl.java
@@ -59,8 +59,7 @@ import org.apache.xpath.objects.XString;
 import org.apache.xpath.res.XPATHErrorResources;
 
 /**
- * This class implements an XPath language parser, using 
- * an XPath input expression string.
+ * Tokenizes and parses XPath expressions.
  * 
  * Ref: https://www.w3.org/TR/xpath-31/
  *      (please also refer to section 'A XPath 3.1 Grammar', within
@@ -72,9 +71,9 @@ import org.apache.xpath.res.XPATHErrorResources;
  *         Henry Zongaro, Christine Li
  *         
  * @author Mukul Gandhi
- *         (XPath 3 language changes, to this class)
+ *         (XPath 3 specific changes, to this class)
  * 
- * @xsl.usage internal
+ * @xsl.usage general
  */
 public class XPathParserImpl
 {
@@ -1045,62 +1044,17 @@ public class XPathParserImpl
       // a FilterExpr. 
       id = Keywords.lookupNodeTest(key);
       if (id == null) {
-    	if ((FunctionTable.XPATH_BUILT_IN_FUNCS_NS_URI).equals(nsUri)) {
-    	   if ("contains".equals(key)) {
-      		  id = FunctionTable.FUNC_CONTAINS;  
-      	   }
-    	   else if ("remove".equals(key)) {
-       		  id = FunctionTable.FUNC_REMOVE;  
-       	   }
-    	   else {
-    		  id = m_functionTable.getFunctionID(key); 
-    	   }
+    	if ((FunctionTable.XPATH_BUILT_IN_FUNCS_NS_URI).equals(nsUri)) {    	   
+    	   id = getFunctionTokenForXPathBuiltinFuncs(key);
     	}    	
-    	else if ((FunctionTable.XPATH_BUILT_IN_MAP_FUNCS_NS_URI).equals(nsUri)) {
-    	   if ("size".equals(key)) {
-          	  id = FunctionTable.FUNC_MAP_SIZE;   
-           }
-    	   else if ("get".equals(key)) {
-     		  id = FunctionTable.FUNC_MAP_GET; 
-     	   }
-    	   else if ("put".equals(key)) {
-      		  id = FunctionTable.FUNC_MAP_PUT; 
-      	   }
-    	   else if ("contains".equals(key)) {
-    		  id = FunctionTable.FUNC_MAP_CONTAINS;  
-    	   }
-    	   else if ("keys".equals(key)) {
-     		  id = FunctionTable.FUNC_MAP_KEYS;  
-     	   }
-    	   else if ("entry".equals(key)) {
-      		  id = FunctionTable.FUNC_MAP_ENTRY;  
-      	   }
-    	   else if ("for-each".equals(key)) {
-       		  id = FunctionTable.FUNC_MAP_FOREACH;  
-       	   }
+    	else if ((FunctionTable.XPATH_BUILT_IN_MAP_FUNCS_NS_URI).equals(nsUri)) {    	       	   
+    	   id = getFunctionTokenForXPathBuiltinMapFuncs(key);
     	}
-    	else if ((FunctionTable.XPATH_BUILT_IN_ARRAY_FUNCS_NS_URI).equals(nsUri)) {
-     	   if ("size".equals(key)) {
-         	  id = FunctionTable.FUNC_ARRAY_SIZE;   
-           }
-     	   else if ("get".equals(key)) {
-     		  id = FunctionTable.FUNC_ARRAY_GET; 
-     	   }
-     	   else if ("put".equals(key)) {
-      		  id = FunctionTable.FUNC_ARRAY_PUT; 
-      	   }
-     	   else if ("append".equals(key)) {
-       		  id = FunctionTable.FUNC_ARRAY_APPEND; 
-       	   }
-     	   else if ("subarray".equals(key)) {
-       		  id = FunctionTable.FUNC_ARRAY_SUBARRAY; 
-       	   }
-     	   else if ("remove".equals(key)) {
-       		  id = FunctionTable.FUNC_ARRAY_REMOVE; 
-       	   }
+    	else if ((FunctionTable.XPATH_BUILT_IN_ARRAY_FUNCS_NS_URI).equals(nsUri)) {     	   
+     	  id = getFunctionTokenForXPathBuiltinArrayFuncs(key);
      	}
     	else {
-    	   id = m_functionTable.getFunctionID(key);
+    	  id = m_functionTable.getFunctionID(key);
     	}
       }
       tok = ((Integer) id).intValue();
@@ -1117,6 +1071,123 @@ public class XPathParserImpl
     return tok;
   }
 
+  /**
+   * Get function token, for XPath built-in functions from namespace
+   * http://www.w3.org/2005/xpath-functions. 
+   */
+  private Object getFunctionTokenForXPathBuiltinFuncs(String key) {	
+		Object id = null;
+		
+		switch (key) {
+		      case "contains":
+			     id = FunctionTable.FUNC_CONTAINS;
+			     break;
+		      case "remove":
+			     id = FunctionTable.FUNC_REMOVE;
+			     break;
+		      case "for-each":
+			     id = FunctionTable.FUNC_FOR_EACH;
+			     break;
+		      case "insert-before":
+			     id = FunctionTable.FUNC_INSERT_BEFORE;
+			     break;
+		      case "head":
+			     id = FunctionTable.FUNC_HEAD;
+			     break;
+		      case "tail":
+			     id = FunctionTable.FUNC_TAIL;
+			     break;
+		      case "reverse":
+				 id = FunctionTable.FUNC_REVERSE;
+				 break;
+			  default:
+				 id = m_functionTable.getFunctionID(key); 
+		}
+		
+		return id;	
+  }
+  
+  /**
+   * Get function token, for XPath built-in map functions from namespace
+   * http://www.w3.org/2005/xpath-functions/map. 
+   */
+  private Object getFunctionTokenForXPathBuiltinMapFuncs(String key) {		
+		Object id = null;
+		
+		switch (key) {
+		      case "size":
+			     id = FunctionTable.FUNC_MAP_SIZE;
+			     break;
+		      case "get":
+			     id = FunctionTable.FUNC_MAP_GET;
+			     break;
+		      case "put":
+			     id = FunctionTable.FUNC_MAP_PUT;
+			     break;
+		      case "contains":
+			     id = FunctionTable.FUNC_MAP_CONTAINS;
+			     break;
+		      case "keys":
+			     id = FunctionTable.FUNC_MAP_KEYS;
+			     break;
+		      case "entry":
+			     id = FunctionTable.FUNC_MAP_ENTRY;
+			     break;
+		      case "for-each":
+			     id = FunctionTable.FUNC_MAP_FOREACH;
+			     break;
+			  default:
+				 // NO OP 
+		}
+		
+		return id;	
+  }
+  
+  /**
+   * Get function token, for XPath built-in array functions from namespace
+   * http://www.w3.org/2005/xpath-functions/array. 
+   */
+  private Object getFunctionTokenForXPathBuiltinArrayFuncs(String key) {	  
+		Object id = null;
+		
+		switch (key) {
+		      case "size":
+			     id = FunctionTable.FUNC_ARRAY_SIZE;
+			     break;
+		      case "get":
+			     id = FunctionTable.FUNC_ARRAY_GET;
+			     break;
+		      case "put":
+			     id = FunctionTable.FUNC_ARRAY_PUT;
+			     break;
+		      case "append":
+			     id = FunctionTable.FUNC_ARRAY_APPEND;
+			     break;
+		      case "subarray":
+			     id = FunctionTable.FUNC_ARRAY_SUBARRAY;
+			     break;
+		      case "remove":
+			     id = FunctionTable.FUNC_ARRAY_REMOVE;
+			     break;
+		      case "insert-before":
+			     id = FunctionTable.FUNC_ARRAY_INSERT_BEFORE;
+			     break;
+		      case "head":
+			     id = FunctionTable.FUNC_ARRAY_HEAD;
+			     break;
+		      case "tail":
+			     id = FunctionTable.FUNC_ARRAY_TAIL;
+			     break;
+		      case "reverse":
+				 id = FunctionTable.FUNC_ARRAY_REVERSE;
+				 break;
+			  default:
+				 // NO OP 
+		}
+		
+		return id;		
+   }
+
   /**
    * Insert room for operation.  This will NOT set
    * the length value of the operation, but will update
diff --git a/src/org/apache/xpath/composite/SequenceTypeSupport.java b/src/org/apache/xpath/composite/SequenceTypeSupport.java
index 6ece7c06..daf48318 100644
--- a/src/org/apache/xpath/composite/SequenceTypeSupport.java
+++ b/src/org/apache/xpath/composite/SequenceTypeSupport.java
@@ -25,6 +25,7 @@ import java.util.Set;
 import javax.xml.transform.SourceLocator;
 import javax.xml.transform.TransformerException;
 
+import org.apache.xalan.templates.XMLNSDecl;
 import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
 import org.apache.xml.dtm.DTM;
 import org.apache.xml.dtm.DTMIterator;
@@ -165,7 +166,7 @@ public class SequenceTypeSupport {
     
     public static String INLINE_FUNCTION_PARAM_TYPECHECK_COUNT_ERROR = "INLINE_FUNCTION_PARAM_TYPECHECK_COUNT_ERROR";
     
-    private static List fPrefixTable;
+    private static List<XMLNSDecl> fPrefixTable;
     
     /**
      * This method converts/casts an XPath 3.1 xdm source value represented by an
@@ -268,6 +269,25 @@ public class SequenceTypeSupport {
             int itemTypeOccurenceIndicator = seqExpectedTypeData.getItemTypeOccurrenceIndicator();
             SequenceTypeKindTest sequenceTypeKindTest = seqExpectedTypeData.getSequenceTypeKindTest();
             
+            if ((srcValue != null) && (sequenceTypeKindTest != null)) {
+            	if (sequenceTypeKindTest.getKindVal() == ITEM_KIND) {
+            	   if (srcValue instanceof XPathArray) {
+            		  XPathArray xpathArr = (XPathArray)srcValue;
+            		  if (itemTypeOccurenceIndicator == OccurenceIndicator.ZERO_OR_MANY) {
+            			 result = xpathArr;   
+            		  }
+            		  else if ((itemTypeOccurenceIndicator == OccurenceIndicator.ONE_OR_MANY) && (xpathArr.size() > 0)) {
+            			 result = xpathArr; 
+            		  }
+            		  else if ((itemTypeOccurenceIndicator == OccurenceIndicator.ZERO_OR_ONE) && (xpathArr.size() <= 1)) {
+            			 result = xpathArr; 
+            		  }
+            		  
+            		  return result;
+            	   }
+            	}
+            }
+            
             if (srcValue instanceof XString) {
                 String srcStrVal = ((XString)srcValue).str();
                 
diff --git a/src/org/apache/xpath/functions/FuncForEach.java b/src/org/apache/xpath/functions/FuncForEach.java
index 163b367e..6ec5a4c8 100644
--- a/src/org/apache/xpath/functions/FuncForEach.java
+++ b/src/org/apache/xpath/functions/FuncForEach.java
@@ -111,7 +111,7 @@ public class FuncForEach extends Function2Args {
                     
         if (arg1 instanceof InlineFunction) {
             InlineFunction inlineFuncArg = (InlineFunction)arg1;
-            validateInlineFunctionParamCardinality(inlineFuncArg, srcLocator);
+            verifyInlineFunctionParamCardinality(inlineFuncArg, srcLocator);
             resultSeq = evaluateFnForEach(xctxt, arg0XsObject, arg0DtmIterator, inlineFuncArg); 
         }
         else if (arg1 instanceof Variable) {
@@ -122,7 +122,7 @@ public class FuncForEach extends Function2Args {
             XObject arg1VarValue = arg1.execute(xctxt);
             if (arg1VarValue instanceof InlineFunction) {
                 InlineFunction inlineFuncArg = (InlineFunction)arg1VarValue;
-                validateInlineFunctionParamCardinality(inlineFuncArg, srcLocator);
+                verifyInlineFunctionParamCardinality(inlineFuncArg, srcLocator);
                 resultSeq = evaluateFnForEach(xctxt, arg0XsObject, arg0DtmIterator, inlineFuncArg);   
             }
             else {
@@ -172,9 +172,9 @@ public class FuncForEach extends Function2Args {
   }
   
   /*
-   * Validate the, number of function parameters, that the inline function is allowed to have for fn:for-each.
+   * Verify the, number of function parameters, that the inline function is allowed to have for fn:for-each.
    */
-  private void validateInlineFunctionParamCardinality(InlineFunction inlineFuncArg, SourceLocator srcLocator) throws 
+  private void verifyInlineFunctionParamCardinality(InlineFunction inlineFuncArg, SourceLocator srcLocator) throws 
                                                                                                 javax.xml.transform.TransformerException {
       List<InlineFunctionParameter> funcParamList = inlineFuncArg.getFuncParamList();
       if (funcParamList.size() != 1) {
diff --git a/src/org/apache/xpath/functions/array/FuncArrayHead.java b/src/org/apache/xpath/functions/array/FuncArrayHead.java
new file mode 100644
index 00000000..9b61005b
--- /dev/null
+++ b/src/org/apache/xpath/functions/array/FuncArrayHead.java
@@ -0,0 +1,74 @@
+/*
+ * 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.xpath.functions.array;
+
+import javax.xml.transform.SourceLocator;
+
+import org.apache.xpath.Expression;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.functions.FunctionOneArg;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XPathArray;
+import org.apache.xpath.operations.Variable;
+
+/**
+ * Implementation of the array:head function.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class FuncArrayHead extends FunctionOneArg {
+	
+	private static final long serialVersionUID = -3207085299844796544L;
+
+	public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+	{
+	    XObject result = null;
+	       
+	    SourceLocator srcLocator = xctxt.getSAXLocator();
+	       
+	    Expression arg0 = getArg0();
+	    
+	    XObject xObject = null;
+	    
+	    if (arg0 instanceof Variable) {
+	       xObject = ((Variable)arg0).execute(xctxt);
+	    }
+	    else {
+	       xObject = arg0.execute(xctxt);
+	    }	    
+	    
+	    if (xObject instanceof XPathArray) {
+	       XPathArray xpathArr = (XPathArray)xObject;
+	       if (xpathArr.size() > 0) {
+	          result = xpathArr.get(0);
+	       }
+	       else {
+	    	  throw new javax.xml.transform.TransformerException("FOAY0001 : An array:head function call's argument "
+	    	  		                                                                     + "cannot be an empty array.", srcLocator);  
+	       }
+	    }
+	    else {
+	       throw new javax.xml.transform.TransformerException("FOAY0001 : The 1st argument of function array:head, "
+	       		                                                                         + "needs to be an array.", srcLocator); 
+	    }
+	    
+	    return result;
+	}
+
+}
diff --git a/src/org/apache/xpath/functions/array/FuncArrayInsertBefore.java b/src/org/apache/xpath/functions/array/FuncArrayInsertBefore.java
new file mode 100644
index 00000000..f734a0fd
--- /dev/null
+++ b/src/org/apache/xpath/functions/array/FuncArrayInsertBefore.java
@@ -0,0 +1,136 @@
+/*
+ * 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.xpath.functions.array;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.transform.SourceLocator;
+
+import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
+import org.apache.xpath.Expression;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.functions.Function3Args;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XPathArray;
+import org.apache.xpath.operations.Variable;
+
+import xml.xpath31.processor.types.XSNumericType;
+
+/**
+ * Implementation of the array:insert-before function.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class FuncArrayInsertBefore extends Function3Args {
+
+	private static final long serialVersionUID = -6993811075719408978L;
+
+	public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+	{
+	    XObject result = null;
+	       
+	    SourceLocator srcLocator = xctxt.getSAXLocator();
+	       
+	    Expression arg0Expr = getArg0();	    
+	    Expression arg1Expr = getArg1();	    
+	    Expression arg2Expr = getArg2();
+	    
+	    XPathArray arg0XPathArr = null;
+	    
+	    List<XObject> nativeArr = null;	    
+	    if (arg0Expr instanceof Variable) {
+	       XObject xObject = ((Variable)arg0Expr).execute(xctxt);
+	       if (xObject instanceof XPathArray) {
+	    	  arg0XPathArr = (XPathArray)xObject;
+		      nativeArr = arg0XPathArr.getNativeArray();
+		   }
+	       else {
+	    	   throw new javax.xml.transform.TransformerException("FORG0006 : The 1st argument of array:insert-before function call, "
+                                                                         + "needs to be an array", srcLocator);   
+	       }
+	    }
+	    else {
+	    	XObject xObject = arg0Expr.execute(xctxt);
+		    if (xObject instanceof XPathArray) {
+		       arg0XPathArr = (XPathArray)xObject;
+			   nativeArr = arg0XPathArr.getNativeArray();
+			}
+		    else {
+		       throw new javax.xml.transform.TransformerException("FORG0006 : The 1st argument of array:insert-before function call, "
+	                                                                         + "needs to be an array", srcLocator);   
+		    }
+	    }
+	    
+	    XObject arg1XObj = null;
+	    if (arg1Expr instanceof Variable) {
+	       arg1XObj = ((Variable)arg1Expr).execute(xctxt);
+	       if (!((arg1XObj instanceof XSNumericType) || (arg1XObj instanceof XNumber))) {
+	    	  throw new javax.xml.transform.TransformerException("FOAY0001 : The 2nd argument of array:insert-before function "
+                                                                                               + "call, needs to be an xs:integer value", srcLocator); 
+	       }
+	    }
+	    else {
+	       arg1XObj = arg1Expr.execute(xctxt);
+	       if (!((arg1XObj instanceof XSNumericType) || (arg1XObj instanceof XNumber))) {
+		      throw new javax.xml.transform.TransformerException("FOAY0001 : The 2nd argument of array:insert-before function "
+	                                                                                           + "call, needs to be an xs:integer value", srcLocator); 
+		   }
+	    }
+	    
+	    XObject arg2XObj = null;
+	    if (arg2Expr instanceof Variable) {
+		   arg2XObj = ((Variable)arg2Expr).execute(xctxt);
+		}
+		else {
+		   arg2XObj = arg2Expr.execute(xctxt);
+		}
+	    
+	    int arg1Int;	    
+	    try {
+	       arg1Int = Integer.valueOf(XslTransformEvaluationHelper.getStrVal(arg1XObj));
+	       int inpArrSize = nativeArr.size();
+	       if ((arg1Int < 1) || (arg1Int > (inpArrSize + 1))) {
+	    	   throw new javax.xml.transform.TransformerException("FOAY0001 : The 2nd argument of array:insert-before function all, needs to be "
+	    	   		                                                       + "an xs:integer value in the range 1 to (array:size($array) + 1) inclusive", srcLocator);  
+	       }	       
+	    }
+	    catch (NumberFormatException ex) {
+	       throw new javax.xml.transform.TransformerException("FOAY0001 : The 2nd argument of array:insert-before function "
+                                                                      + "call, needs to be an xs:integer value", srcLocator); 
+	    }
+	    
+	    List<XObject> resultL = nativeArr.subList(0, arg1Int - 1);
+	    List<XObject> resultR = nativeArr.subList(arg1Int - 1, nativeArr.size());
+	    
+	    List<XObject> resultNativeArr = new ArrayList<XObject>();
+	    resultNativeArr.addAll(resultL);
+	    resultNativeArr.add(arg2XObj);
+	    resultNativeArr.addAll(resultR);
+	    
+	    XPathArray resultArr = new XPathArray();
+	    resultArr.setNativeArray(resultNativeArr);
+	    
+	    result = resultArr;
+	    
+	    return result;
+	}
+
+}
diff --git a/src/org/apache/xpath/functions/array/FuncArrayReverse.java b/src/org/apache/xpath/functions/array/FuncArrayReverse.java
new file mode 100644
index 00000000..ddb75baf
--- /dev/null
+++ b/src/org/apache/xpath/functions/array/FuncArrayReverse.java
@@ -0,0 +1,76 @@
+/*
+ * 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.xpath.functions.array;
+
+import java.util.Collections;
+import java.util.List;
+
+import javax.xml.transform.SourceLocator;
+
+import org.apache.xpath.Expression;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.functions.FunctionOneArg;
+import org.apache.xpath.objects.ResultSequence;
+import org.apache.xpath.objects.XNodeSet;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XPathArray;
+import org.apache.xpath.operations.Variable;
+
+import xml.xpath31.processor.types.XSInteger;
+
+/**
+ * Implementation of the array:reverse function.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class FuncArrayReverse extends FunctionOneArg {
+
+	private static final long serialVersionUID = 8786348949335466009L;
+
+	public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+	{
+	    XObject result = null;
+	       
+	    SourceLocator srcLocator = xctxt.getSAXLocator();
+	       
+	    Expression arg0 = getArg0();
+	    
+	    XObject xObject = null;
+	    
+	    if (arg0 instanceof Variable) {
+	       xObject = ((Variable)arg0).execute(xctxt);
+	    }
+	    else {
+	       xObject = arg0.execute(xctxt);
+	    }
+	    
+	    if (xObject instanceof XPathArray) {
+	       XPathArray xpathArr = (XPathArray)xObject;
+	       List<XObject> nativeArr = xpathArr.getNativeArray();
+	       Collections.reverse(nativeArr);
+	       result = xpathArr;
+	    }
+	    else {
+	    	throw new javax.xml.transform.TransformerException("FOAY0001 : The 1st argument of function array:reverse, needs to be an array.", srcLocator);  	
+	    }
+	    
+	    return result;
+	}
+
+}
diff --git a/src/org/apache/xpath/functions/array/FuncArrayTail.java b/src/org/apache/xpath/functions/array/FuncArrayTail.java
new file mode 100644
index 00000000..57c74e5e
--- /dev/null
+++ b/src/org/apache/xpath/functions/array/FuncArrayTail.java
@@ -0,0 +1,82 @@
+/*
+ * 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.xpath.functions.array;
+
+import java.util.List;
+
+import javax.xml.transform.SourceLocator;
+
+import org.apache.xpath.Expression;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.functions.FunctionOneArg;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XPathArray;
+import org.apache.xpath.operations.Variable;
+
+/**
+ * Implementation of the array:tail function.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class FuncArrayTail extends FunctionOneArg {
+	
+	private static final long serialVersionUID = 5783190267382201534L;
+
+	public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+	{
+	    XObject result = null;
+	       
+	    SourceLocator srcLocator = xctxt.getSAXLocator();
+	       
+	    Expression arg0 = getArg0();
+	    
+	    XObject xObject = null;
+	    
+	    if (arg0 instanceof Variable) {
+	       xObject = ((Variable)arg0).execute(xctxt);
+	    }
+	    else {
+	       xObject = arg0.execute(xctxt);
+	    }	    
+	    
+	    if (xObject instanceof XPathArray) {
+	       XPathArray xpathArr = (XPathArray)xObject;
+	       if (xpathArr.size() > 0) {
+	    	  List<XObject> nativeArr = xpathArr.getNativeArray();
+	    	  
+	    	  List<XObject> newNativeArr = nativeArr.subList(1, nativeArr.size());
+	    	  xpathArr = new XPathArray();
+	    	  xpathArr.setNativeArray(newNativeArr);
+	    	  
+	    	  result = xpathArr;
+	       }
+	       else {
+	    	  throw new javax.xml.transform.TransformerException("FOAY0001 : An array:tail function call's argument "
+	    	  		                                                                     + "cannot be an empty array.", srcLocator);  
+	       }
+	    }
+	    else {
+	       throw new javax.xml.transform.TransformerException("FOAY0001 : The 1st argument of function array:tail, "
+	       		                                                                         + "needs to be an array.", srcLocator); 
+	    }
+	    
+	    return result;
+	}
+
+}
diff --git a/tests/org/apache/xalan/xpath3/InlineFunctionItemExprTests.java b/tests/org/apache/xalan/xpath3/InlineFunctionItemExprTests.java
index f0fb9ac9..267109ce 100644
--- a/tests/org/apache/xalan/xpath3/InlineFunctionItemExprTests.java
+++ b/tests/org/apache/xalan/xpath3/InlineFunctionItemExprTests.java
@@ -23,8 +23,7 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 
 /**
- * XPath 3.1 "function item" inline function expression test 
- * cases.
+ * XPath 3.1 inline function expression test cases.
  * 
  * @author Mukul Gandhi <mu...@apache.org>
  * 
diff --git a/tests/org/apache/xalan/xpath3/XPathArrayTests.java b/tests/org/apache/xalan/xpath3/XPathArrayTests.java
index bc9359a3..9f92a78f 100644
--- a/tests/org/apache/xalan/xpath3/XPathArrayTests.java
+++ b/tests/org/apache/xalan/xpath3/XPathArrayTests.java
@@ -127,5 +127,45 @@ public class XPathArrayTests extends XSLTransformTestsUtil {
         
         runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
     }
+    
+    @Test
+    public void xslArrayTest9() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test9.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test9.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test9.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslArrayTest10() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test10.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test10.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test10.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslArrayTest11() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test11.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test11.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test11.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslArrayTest12() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test12.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test12.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test12.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
 
 }
diff --git a/tests/org/apache/xalan/xpath3/XPathMapTests.java b/tests/org/apache/xalan/xpath3/XPathMapTests.java
index b0aae9a3..385bb3d3 100644
--- a/tests/org/apache/xalan/xpath3/XPathMapTests.java
+++ b/tests/org/apache/xalan/xpath3/XPathMapTests.java
@@ -207,5 +207,45 @@ public class XPathMapTests extends XSLTransformTestsUtil {
         
         runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
     }
+    
+    @Test
+    public void xslMapTest17() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test17.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test17.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test17.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslMapTest18() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test18.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test18.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test18.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslMapTest19() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test19.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test19.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test19.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslMapTest20() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test20.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test20.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test20.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
 
 }
diff --git a/tests/xpath_array/gold/test10.out b/tests/xpath_array/gold/test10.out
new file mode 100644
index 00000000..f301f596
--- /dev/null
+++ b/tests/xpath_array/gold/test10.out
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one resultSeqSize="1">5</one>
+  <two resultSeqSize="1">a b</two>
+</result>
diff --git a/tests/xpath_array/gold/test11.out b/tests/xpath_array/gold/test11.out
new file mode 100644
index 00000000..82dec5ce
--- /dev/null
+++ b/tests/xpath_array/gold/test11.out
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one resultArrSize="3">6 7 8</one>
+  <two resultArrSize="0"/>
+</result>
diff --git a/tests/xpath_array/gold/test12.out b/tests/xpath_array/gold/test12.out
new file mode 100644
index 00000000..f8002b89
--- /dev/null
+++ b/tests/xpath_array/gold/test12.out
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>d c b a</one>
+</result>
diff --git a/tests/xpath_array/gold/test9.out b/tests/xpath_array/gold/test9.out
new file mode 100644
index 00000000..8b68129b
--- /dev/null
+++ b/tests/xpath_array/gold/test9.out
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one resultArrSize="5">a b x y c d</one>
+  <two resultArrSize="5">a b c d x y</two>
+  <three resultArrSize="5">a b x y c d</three>
+</result>
diff --git a/tests/xpath_array/test10.xsl b/tests/xpath_array/test10.xsl
new file mode 100644
index 00000000..e4939080
--- /dev/null
+++ b/tests/xpath_array/test10.xsl
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                xmlns:array="http://www.w3.org/2005/xpath-functions/array"
+                exclude-result-prefixes="xs array"
+                version="3.0">
+                
+    <!-- Author: mukulg@apache.org -->
+    
+    <!-- An XSLT 3.0 test case to test, XPath 3.1 function 
+         array:head.
+    -->                              
+
+    <xsl:output method="xml" indent="yes"/>
+
+    <xsl:template match="/">
+       <result>
+         <xsl:variable name="arr1" select="[5, 6, 7, 8]" as="array(xs:integer)"/>
+         
+         <xsl:variable name="arr2" select="['a', 'b']" as="array(xs:string)"/>
+         <xsl:variable name="arr3" select="['c', 'd']" as="array(xs:string)"/>         
+         
+         <xsl:variable name="arr4" select="[$arr2, $arr3]" as="array(*)"/>
+                           
+         <xsl:variable name="afterArrHead1" select="array:head($arr1)"/>
+         <xsl:variable name="afterArrHead2" select="array:head($arr4)"/>
+          
+         <one resultSeqSize="{count($afterArrHead1)}">
+           <xsl:value-of select="$afterArrHead1"/>
+         </one>
+         <two resultSeqSize="{count($afterArrHead2)}">
+           <xsl:value-of select="$afterArrHead2"/>
+         </two>
+       </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/xpath_array/test11.xsl b/tests/xpath_array/test11.xsl
new file mode 100644
index 00000000..51bd5c32
--- /dev/null
+++ b/tests/xpath_array/test11.xsl
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                xmlns:array="http://www.w3.org/2005/xpath-functions/array"
+                exclude-result-prefixes="xs array"
+                version="3.0">
+                
+    <!-- Author: mukulg@apache.org -->
+    
+    <!-- An XSLT 3.0 test case to test, XPath 3.1 function 
+         array:tail.
+    -->                              
+
+    <xsl:output method="xml" indent="yes"/>
+
+    <xsl:template match="/">
+       <result>
+         <xsl:variable name="arr1" select="[5, 6, 7, 8]" as="array(xs:integer)"/>         
+         <xsl:variable name="arr2" select="[5]" as="array(xs:integer)"/>
+                           
+         <xsl:variable name="afterArrTail1" select="array:tail($arr1)"/>
+         <xsl:variable name="afterArrTail2" select="array:tail($arr2)"/>
+          
+         <one resultArrSize="{array:size($afterArrTail1)}">
+           <xsl:value-of select="$afterArrTail1"/>
+         </one>
+         <two resultArrSize="{array:size($afterArrTail2)}">
+           <xsl:value-of select="$afterArrTail2"/>
+         </two>
+       </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/xpath_array/test12.xsl b/tests/xpath_array/test12.xsl
new file mode 100644
index 00000000..2dbfa0b6
--- /dev/null
+++ b/tests/xpath_array/test12.xsl
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                xmlns:array="http://www.w3.org/2005/xpath-functions/array"
+                exclude-result-prefixes="xs array"
+                version="3.0">
+                
+    <!-- Author: mukulg@apache.org -->
+    
+    <!-- An XSLT 3.0 test case to test, XPath 3.1 function 
+         array:reverse.
+    -->                              
+
+    <xsl:output method="xml" indent="yes"/>
+
+    <xsl:template match="/">
+       <result>
+         <xsl:variable name="arr1" select="['a', 'b', 'c', 'd']" as="array(xs:string)"/>          
+         <one>
+           <xsl:value-of select="array:reverse($arr1)"/>
+         </one>
+       </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/xpath_array/test9.xsl b/tests/xpath_array/test9.xsl
new file mode 100644
index 00000000..308504da
--- /dev/null
+++ b/tests/xpath_array/test9.xsl
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                xmlns:array="http://www.w3.org/2005/xpath-functions/array"
+                exclude-result-prefixes="xs array"
+                version="3.0">
+                
+    <!-- Author: mukulg@apache.org -->
+    
+    <!-- An XSLT 3.0 test case to test, XPath 3.1 function 
+         array:insert-before.
+    -->                              
+
+    <xsl:output method="xml" indent="yes"/>
+
+    <xsl:template match="/">
+       <result>
+         <xsl:variable name="arr1" select="['a', 'b', 'c', 'd']" as="array(xs:string)"/>
+         <xsl:variable name="seq1" select="('x', 'y')" as="xs:string*"/>
+         <xsl:variable name="arr2" select="['x', 'y']" as="array(xs:string)"/>
+         <xsl:variable name="arrAfterInsertBefore1" select="array:insert-before($arr1, 3, $seq1)" as="array(*)"/>
+         <xsl:variable name="arrAfterInsertBefore2" select="array:insert-before($arr1, 5, $seq1)" as="array(*)"/>
+         <xsl:variable name="arrAfterInsertBefore3" select="array:insert-before($arr1, 3, $arr2)" as="array(*)"/>
+         <one resultArrSize="{array:size($arrAfterInsertBefore1)}">
+           <xsl:value-of select="$arrAfterInsertBefore1"/>
+         </one>
+         <two resultArrSize="{array:size($arrAfterInsertBefore2)}">
+           <xsl:value-of select="$arrAfterInsertBefore2"/>
+         </two>
+         <three resultArrSize="{array:size($arrAfterInsertBefore3)}">
+           <xsl:value-of select="$arrAfterInsertBefore3"/>
+         </three>
+       </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/xpath_maps/gold/test17.out b/tests/xpath_maps/gold/test17.out
new file mode 100644
index 00000000..b23e43d3
--- /dev/null
+++ b/tests/xpath_maps/gold/test17.out
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one itemCount="2">
+    <ok>true ### true</ok>
+  </one>
+</result>
diff --git a/tests/xpath_maps/gold/test18.out b/tests/xpath_maps/gold/test18.out
new file mode 100644
index 00000000..b23e43d3
--- /dev/null
+++ b/tests/xpath_maps/gold/test18.out
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one itemCount="2">
+    <ok>true ### true</ok>
+  </one>
+</result>
diff --git a/tests/xpath_maps/gold/test19.out b/tests/xpath_maps/gold/test19.out
new file mode 100644
index 00000000..b23e43d3
--- /dev/null
+++ b/tests/xpath_maps/gold/test19.out
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one itemCount="2">
+    <ok>true ### true</ok>
+  </one>
+</result>
diff --git a/tests/xpath_maps/gold/test20.out b/tests/xpath_maps/gold/test20.out
new file mode 100644
index 00000000..b23e43d3
--- /dev/null
+++ b/tests/xpath_maps/gold/test20.out
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one itemCount="2">
+    <ok>true ### true</ok>
+  </one>
+</result>
diff --git a/tests/xpath_maps/test15.xsl b/tests/xpath_maps/test15.xsl
index 21fed8b0..240b0c45 100644
--- a/tests/xpath_maps/test15.xsl
+++ b/tests/xpath_maps/test15.xsl
@@ -18,12 +18,12 @@
 	   <xsl:variable name="seq1" select="map:for-each($map1, $action1)"/>
 	   <one itemCount="{count($seq1)}">
 	     <ok>
-		   <xsl:call-template name="exists">
+		   <xsl:call-template name="contains">
 		     <xsl:with-param name="seq1" select="$seq1"/>
 			 <xsl:with-param name="value1" select="1"/>
 		   </xsl:call-template>
 		   <xsl:text> ### </xsl:text>
-		   <xsl:call-template name="exists">
+		   <xsl:call-template name="contains">
 		     <xsl:with-param name="seq1" select="$seq1"/>
 			 <xsl:with-param name="value1" select="2"/>
 		   </xsl:call-template>
@@ -34,7 +34,7 @@
    
    <!-- An XSL named template, to check whether a sequence 
         contains a specific value. -->
-   <xsl:template name="exists" as="xs:boolean">
+   <xsl:template name="contains" as="xs:boolean">
      <xsl:param name="seq1" as="xs:integer*"/>
 	 <xsl:param name="value1" as="xs:integer"/>
 	 <xsl:variable name="temp1">
diff --git a/tests/xpath_maps/test16.xsl b/tests/xpath_maps/test16.xsl
index 6d23b024..c84edc84 100644
--- a/tests/xpath_maps/test16.xsl
+++ b/tests/xpath_maps/test16.xsl
@@ -18,12 +18,12 @@
 	   <xsl:variable name="seq1" select="distinct-values(map:for-each($map1, $action1))"/>
 	   <one itemCount="{count($seq1)}">
 	     <ok>
-		   <xsl:call-template name="exists">
+		   <xsl:call-template name="contains">
 		     <xsl:with-param name="seq1" select="$seq1"/>
 			 <xsl:with-param name="value1" select="'yes'"/>
 		   </xsl:call-template>
 		   <xsl:text> ### </xsl:text>
-		   <xsl:call-template name="exists">
+		   <xsl:call-template name="contains">
 		     <xsl:with-param name="seq1" select="$seq1"/>
 			 <xsl:with-param name="value1" select="'no'"/>
 		   </xsl:call-template>
@@ -34,7 +34,7 @@
    
    <!-- An XSL named template, to check whether a sequence 
         contains a specific value. -->
-   <xsl:template name="exists" as="xs:boolean">
+   <xsl:template name="contains" as="xs:boolean">
      <xsl:param name="seq1" as="xs:string*"/>
 	 <xsl:param name="value1" as="xs:string"/>
 	 <xsl:variable name="temp1">
diff --git a/tests/xpath_maps/test16.xsl b/tests/xpath_maps/test17.xsl
similarity index 66%
copy from tests/xpath_maps/test16.xsl
copy to tests/xpath_maps/test17.xsl
index 6d23b024..54c09a09 100644
--- a/tests/xpath_maps/test16.xsl
+++ b/tests/xpath_maps/test17.xsl
@@ -1,8 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                 xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                xmlns:fn0="http://fn0"
                 xmlns:map="http://www.w3.org/2005/xpath-functions/map"
-				exclude-result-prefixes="xs map"
+				exclude-result-prefixes="xs fn0 map"
                 version="3.0">
 				
    <!-- Author: mukulg@apache.org -->                 
@@ -18,42 +19,19 @@
 	   <xsl:variable name="seq1" select="distinct-values(map:for-each($map1, $action1))"/>
 	   <one itemCount="{count($seq1)}">
 	     <ok>
-		   <xsl:call-template name="exists">
-		     <xsl:with-param name="seq1" select="$seq1"/>
-			 <xsl:with-param name="value1" select="'yes'"/>
-		   </xsl:call-template>
-		   <xsl:text> ### </xsl:text>
-		   <xsl:call-template name="exists">
-		     <xsl:with-param name="seq1" select="$seq1"/>
-			 <xsl:with-param name="value1" select="'no'"/>
-		   </xsl:call-template>
+		   <xsl:value-of select="fn0:contains($seq1, 'yes')"/> ### <xsl:value-of select="fn0:contains($seq1, 'no')"/> 
 		 </ok>
 	   </one>
 	 </result>
    </xsl:template>
    
-   <!-- An XSL named template, to check whether a sequence 
+   <!-- An XSL function, to check whether a sequence 
         contains a specific value. -->
-   <xsl:template name="exists" as="xs:boolean">
+   <xsl:function name="fn0:contains" as="xs:boolean">
      <xsl:param name="seq1" as="xs:string*"/>
 	 <xsl:param name="value1" as="xs:string"/>
-	 <xsl:variable name="temp1">
-	   <xsl:for-each select="$seq1">
-	      <xsl:variable name="x1" select="."/>
-	      <xsl:if test="$x1 eq $value1">
-		    <yes/>
-		  </xsl:if>
-	   </xsl:for-each>
-	 </xsl:variable>
-	 <xsl:choose>
-	   <xsl:when test="$temp1/yes">
-	      <xsl:value-of select="xs:boolean(1)"/>
-	   </xsl:when>
-	   <xsl:otherwise>
-	      <xsl:value-of select="xs:boolean(0)"/>
-	   </xsl:otherwise>
-	 </xsl:choose>
-   </xsl:template>
+	 <xsl:sequence select="some $v1 in $seq1 satisfies $v1 eq $value1"/>
+   </xsl:function>
    
    <!--
       * Licensed to the Apache Software Foundation (ASF) under one
diff --git a/tests/xpath_maps/test15.xsl b/tests/xpath_maps/test18.xsl
similarity index 66%
copy from tests/xpath_maps/test15.xsl
copy to tests/xpath_maps/test18.xsl
index 21fed8b0..66fe3a5b 100644
--- a/tests/xpath_maps/test15.xsl
+++ b/tests/xpath_maps/test18.xsl
@@ -1,8 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                 xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                xmlns:fn0="http://fn0"
                 xmlns:map="http://www.w3.org/2005/xpath-functions/map"
-				exclude-result-prefixes="xs map"
+				exclude-result-prefixes="xs fn0 map"
                 version="3.0">
                 
    <!-- Author: mukulg@apache.org -->                 
@@ -18,42 +19,19 @@
 	   <xsl:variable name="seq1" select="map:for-each($map1, $action1)"/>
 	   <one itemCount="{count($seq1)}">
 	     <ok>
-		   <xsl:call-template name="exists">
-		     <xsl:with-param name="seq1" select="$seq1"/>
-			 <xsl:with-param name="value1" select="1"/>
-		   </xsl:call-template>
-		   <xsl:text> ### </xsl:text>
-		   <xsl:call-template name="exists">
-		     <xsl:with-param name="seq1" select="$seq1"/>
-			 <xsl:with-param name="value1" select="2"/>
-		   </xsl:call-template>
+		   <xsl:value-of select="fn0:contains($seq1, 1)"/> ### <xsl:value-of select="fn0:contains($seq1, 2)"/>
 		 </ok>
 	   </one>
 	 </result>
    </xsl:template>
    
-   <!-- An XSL named template, to check whether a sequence 
+   <!-- An XSL function, to check whether a sequence 
         contains a specific value. -->
-   <xsl:template name="exists" as="xs:boolean">
+   <xsl:function name="fn0:contains" as="xs:boolean">
      <xsl:param name="seq1" as="xs:integer*"/>
 	 <xsl:param name="value1" as="xs:integer"/>
-	 <xsl:variable name="temp1">
-	   <xsl:for-each select="$seq1">
-	      <xsl:variable name="x1" select="."/>
-	      <xsl:if test="$x1 eq $value1">
-		    <yes/>
-		  </xsl:if>
-	   </xsl:for-each>
-	 </xsl:variable>
-	 <xsl:choose>
-	   <xsl:when test="$temp1/yes">
-	      <xsl:value-of select="xs:boolean(1)"/>
-	   </xsl:when>
-	   <xsl:otherwise>
-	      <xsl:value-of select="xs:boolean(0)"/>
-	   </xsl:otherwise>
-	 </xsl:choose>
-   </xsl:template>
+	 <xsl:sequence select="some $v1 in $seq1 satisfies $v1 eq $value1"/>
+   </xsl:function>
    
    <!--
       * Licensed to the Apache Software Foundation (ASF) under one
diff --git a/tests/xpath_maps/test15.xsl b/tests/xpath_maps/test19.xsl
similarity index 91%
copy from tests/xpath_maps/test15.xsl
copy to tests/xpath_maps/test19.xsl
index 21fed8b0..c37c3691 100644
--- a/tests/xpath_maps/test15.xsl
+++ b/tests/xpath_maps/test19.xsl
@@ -18,12 +18,12 @@
 	   <xsl:variable name="seq1" select="map:for-each($map1, $action1)"/>
 	   <one itemCount="{count($seq1)}">
 	     <ok>
-		   <xsl:call-template name="exists">
+		   <xsl:call-template name="contains">
 		     <xsl:with-param name="seq1" select="$seq1"/>
 			 <xsl:with-param name="value1" select="1"/>
 		   </xsl:call-template>
 		   <xsl:text> ### </xsl:text>
-		   <xsl:call-template name="exists">
+		   <xsl:call-template name="contains">
 		     <xsl:with-param name="seq1" select="$seq1"/>
 			 <xsl:with-param name="value1" select="2"/>
 		   </xsl:call-template>
@@ -33,17 +33,19 @@
    </xsl:template>
    
    <!-- An XSL named template, to check whether a sequence 
-        contains a specific value. -->
-   <xsl:template name="exists" as="xs:boolean">
+        contains a specific value.
+   -->
+   <xsl:template name="contains" as="xs:boolean">
      <xsl:param name="seq1" as="xs:integer*"/>
 	 <xsl:param name="value1" as="xs:integer"/>
 	 <xsl:variable name="temp1">
-	   <xsl:for-each select="$seq1">
+	   <xsl:iterate select="$seq1">
 	      <xsl:variable name="x1" select="."/>
 	      <xsl:if test="$x1 eq $value1">
 		    <yes/>
+		    <xsl:break/>
 		  </xsl:if>
-	   </xsl:for-each>
+	   </xsl:iterate>
 	 </xsl:variable>
 	 <xsl:choose>
 	   <xsl:when test="$temp1/yes">
diff --git a/tests/xpath_maps/test16.xsl b/tests/xpath_maps/test20.xsl
similarity index 91%
copy from tests/xpath_maps/test16.xsl
copy to tests/xpath_maps/test20.xsl
index 6d23b024..75d57586 100644
--- a/tests/xpath_maps/test16.xsl
+++ b/tests/xpath_maps/test20.xsl
@@ -18,12 +18,12 @@
 	   <xsl:variable name="seq1" select="distinct-values(map:for-each($map1, $action1))"/>
 	   <one itemCount="{count($seq1)}">
 	     <ok>
-		   <xsl:call-template name="exists">
+		   <xsl:call-template name="contains">
 		     <xsl:with-param name="seq1" select="$seq1"/>
 			 <xsl:with-param name="value1" select="'yes'"/>
 		   </xsl:call-template>
 		   <xsl:text> ### </xsl:text>
-		   <xsl:call-template name="exists">
+		   <xsl:call-template name="contains">
 		     <xsl:with-param name="seq1" select="$seq1"/>
 			 <xsl:with-param name="value1" select="'no'"/>
 		   </xsl:call-template>
@@ -33,17 +33,19 @@
    </xsl:template>
    
    <!-- An XSL named template, to check whether a sequence 
-        contains a specific value. -->
-   <xsl:template name="exists" as="xs:boolean">
+        contains a specific value.
+   -->
+   <xsl:template name="contains" as="xs:boolean">
      <xsl:param name="seq1" as="xs:string*"/>
 	 <xsl:param name="value1" as="xs:string"/>
 	 <xsl:variable name="temp1">
-	   <xsl:for-each select="$seq1">
+	   <xsl:iterate select="$seq1">
 	      <xsl:variable name="x1" select="."/>
 	      <xsl:if test="$x1 eq $value1">
 		    <yes/>
+		    <xsl:break/>
 		  </xsl:if>
-	   </xsl:for-each>
+	   </xsl:iterate>
 	 </xsl:variable>
 	 <xsl:choose>
 	   <xsl:when test="$temp1/yes">


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xalan.apache.org
For additional commands, e-mail: commits-help@xalan.apache.org