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/08/29 12:20:13 UTC

[xalan-java] branch xalan-j_xslt3.0 updated: committing implementation of xpath 3.1 functions fn:max, fn:min and few new related working test cases as well. also committing minor related xalanj codebase corrections, on this branch.

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 035c9678 committing implementation of xpath 3.1 functions fn:max, fn:min and few new related working test cases as well. also committing minor related xalanj codebase corrections, on this branch.
     new 5bb75fa9 Merge pull request #68 from mukulga/xalan-j_xslt3.0_mukul
035c9678 is described below

commit 035c9678444944f4efffc6dbcfdd9c41902f3b6b
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Tue Aug 29 17:45:11 2023 +0530

    committing implementation of xpath 3.1 functions fn:max, fn:min and few new related working test cases as well. also committing minor related xalanj codebase corrections, on this branch.
---
 src/org/apache/xpath/compiler/FunctionTable.java   |  15 +-
 src/org/apache/xpath/compiler/Keywords.java        |   6 +
 src/org/apache/xpath/functions/FuncAvg.java        |   4 +-
 .../apache/xpath/functions/FuncCurrentDate.java    |   4 +-
 src/org/apache/xpath/functions/FuncMax.java        | 307 +++++++++++++++++++++
 src/org/apache/xpath/functions/FuncMin.java        | 307 +++++++++++++++++++++
 src/org/apache/xpath/xs/types/XSAnyAtomicType.java |   4 +-
 src/org/apache/xpath/xs/types/XSCtrType.java       |   6 +-
 src/org/apache/xpath/xs/types/XSDate.java          |   6 +-
 src/org/apache/xpath/xs/types/XSDouble.java        |  27 +-
 src/org/apache/xpath/xs/types/XSNumericType.java   |   4 +-
 src/org/apache/xpath/xs/types/XSUntyped.java       |   2 +-
 tests/fn_max/gold/test1.out                        |   7 +
 tests/fn_max/gold/test2.out                        |   4 +
 tests/fn_max/test1.xsl                             |  66 +++++
 tests/fn_max/test1_a.xml                           |   8 +
 tests/fn_max/test2.xsl                             |  47 ++++
 tests/fn_min/gold/test1.out                        |   7 +
 tests/fn_min/gold/test2.out                        |   4 +
 tests/fn_min/test1.xsl                             |  66 +++++
 tests/fn_min/test1_a.xml                           |   8 +
 tests/fn_min/test2.xsl                             |  47 ++++
 tests/org/apache/xalan/xpath3/FnMaxTests.java      |  72 +++++
 tests/org/apache/xalan/xpath3/FnMinTests.java      |  72 +++++
 tests/org/apache/xalan/xslt3/AllXsl3Tests.java     |   4 +-
 25 files changed, 1078 insertions(+), 26 deletions(-)

diff --git a/src/org/apache/xpath/compiler/FunctionTable.java b/src/org/apache/xpath/compiler/FunctionTable.java
index e8e3b92b..7b62e43f 100644
--- a/src/org/apache/xpath/compiler/FunctionTable.java
+++ b/src/org/apache/xpath/compiler/FunctionTable.java
@@ -311,6 +311,12 @@ public class FunctionTable
   
   /** The 'avg()' id. */
   public static final int FUNC_AVG = 95;
+  
+  /** The 'max()' id. */
+  public static final int FUNC_MAX = 96;
+  
+  /** The 'min()' id. */
+  public static final int FUNC_MIN = 97;
 
   // Proprietary
 
@@ -368,7 +374,7 @@ public class FunctionTable
    * Number of built in functions. Be sure to update this as
    * built-in functions are added.
    */
-  private static final int NUM_BUILT_IN_FUNCS = 96;
+  private static final int NUM_BUILT_IN_FUNCS = 98;
 
   /**
    * Number of built-in functions that may be added.
@@ -561,7 +567,8 @@ public class FunctionTable
       org.apache.xpath.functions.FuncParseXmlFragment.class;
     
     m_functions[FUNC_AVG] = org.apache.xpath.functions.FuncAvg.class;
-    
+    m_functions[FUNC_MAX] = org.apache.xpath.functions.FuncMax.class;
+    m_functions[FUNC_MIN] = org.apache.xpath.functions.FuncMin.class;
   }
 
   static{
@@ -762,6 +769,10 @@ public class FunctionTable
          
          m_functionID.put(Keywords.FUNC_AVG,
                          new Integer(FunctionTable.FUNC_AVG));
+         m_functionID.put(Keywords.FUNC_MAX,
+                         new Integer(FunctionTable.FUNC_MAX));
+         m_functionID.put(Keywords.FUNC_MIN,
+                         new Integer(FunctionTable.FUNC_MIN));
   }
   
   public FunctionTable(){
diff --git a/src/org/apache/xpath/compiler/Keywords.java b/src/org/apache/xpath/compiler/Keywords.java
index be9b8cde..c7541dab 100644
--- a/src/org/apache/xpath/compiler/Keywords.java
+++ b/src/org/apache/xpath/compiler/Keywords.java
@@ -422,6 +422,12 @@ public class Keywords
   /** avg function string. */
   public static final String FUNC_AVG = "avg";
   
+  /** max function string. */
+  public static final String FUNC_MAX = "max";
+  
+  /** min function string. */
+  public static final String FUNC_MIN = "min";
+  
   // Proprietary, built in functions
 
   /** current function string (Proprietary). */
diff --git a/src/org/apache/xpath/functions/FuncAvg.java b/src/org/apache/xpath/functions/FuncAvg.java
index 00cf684b..1809b772 100644
--- a/src/org/apache/xpath/functions/FuncAvg.java
+++ b/src/org/apache/xpath/functions/FuncAvg.java
@@ -64,8 +64,8 @@ public class FuncAvg extends FunctionOneArg
          result = new ResultSequence();
       }
       
-      // average calculation involving for example, xs:duration values and 
-      // its subtypes. TO DO
+      // TO DO : average calculation involving for example, xs:duration and 
+      // its subtypes.
       
       return result;
   }
diff --git a/src/org/apache/xpath/functions/FuncCurrentDate.java b/src/org/apache/xpath/functions/FuncCurrentDate.java
index 52166951..925da226 100644
--- a/src/org/apache/xpath/functions/FuncCurrentDate.java
+++ b/src/org/apache/xpath/functions/FuncCurrentDate.java
@@ -52,10 +52,10 @@ public class FuncCurrentDate extends Function {
    */
   public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException {
     
-    XSDate xsDate = new XSDate(xctxt.getCurrentDateTime(), xctxt.getTimezone());
+    XSDate xsDate = new XSDate(xctxt.getCurrentDateTime(), xctxt.getTimezone());    
     xsDate.setPopulatedFromFnCurrentDate(true);
 
-    return (XObject)xsDate;
+    return xsDate;
   }
 
   /**
diff --git a/src/org/apache/xpath/functions/FuncMax.java b/src/org/apache/xpath/functions/FuncMax.java
new file mode 100644
index 00000000..3f8e7642
--- /dev/null
+++ b/src/org/apache/xpath/functions/FuncMax.java
@@ -0,0 +1,307 @@
+/*
+ * 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;
+
+import javax.xml.transform.SourceLocator;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xpath.XPathCollationSupport;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.ResultSequence;
+import org.apache.xpath.objects.XNodeSet;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XString;
+import org.apache.xpath.operations.Variable;
+import org.apache.xpath.res.XPATHErrorResources;
+import org.apache.xpath.xs.types.XSDate;
+import org.apache.xpath.xs.types.XSDouble;
+import org.apache.xpath.xs.types.XSNumericType;
+import org.apache.xpath.xs.types.XSString;
+import org.apache.xpath.xs.types.XSUntyped;
+import org.apache.xpath.xs.types.XSUntypedAtomic;
+
+/**
+ * Implementation of an XPath 3.1 function fn:max.
+ * 
+ * Ref : https://www.w3.org/TR/xpath-functions-31/#func-max
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class FuncMax extends FunctionMultiArgs
+{
+
+   private static final long serialVersionUID = 6488632087250018194L;
+    
+   /**
+    * The number of arguments passed to the fn:max function 
+    * call.
+    */
+   private int numOfArgs = 0;
+
+   /**
+   * Execute the function. The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {          
+      XObject result = null;
+      
+      SourceLocator srcLocator = xctxt.getSAXLocator();
+      
+      XObject xObjArg0 = null;
+      
+      ResultSequence convetedInpSequence = new ResultSequence(); 
+      
+      if (m_arg0 instanceof Variable) {
+         xObjArg0 = ((Variable)m_arg0).execute(xctxt);           
+      }
+      else {
+         xObjArg0 = m_arg0.execute(xctxt); 
+      }
+      
+      int doubleItemCount = 0;
+      int strItemCount = 0;
+      int dateItemCount = 0;
+      
+      if (xObjArg0 instanceof XNodeSet) {
+         // If for all the nodes of an input sequence, the node's string
+         // value can be cast to xs:double, we shall be able to process
+         // such a nodeset successfully, to be able to find a numeric
+         // maximum value from these nodes.
+         XNodeSet xsObjNodeSet = (XNodeSet)xObjArg0;
+         DTMIterator dtmIter = xsObjNodeSet.iterRaw();
+         
+         int nextNodeDtmHandle;
+         
+         while ((nextNodeDtmHandle = dtmIter.nextNode()) != DTM.NULL) {       
+            XNodeSet xdmNode = new XNodeSet(nextNodeDtmHandle, xctxt);
+            String nodeStrVal = xdmNode.str();
+            try {
+               convetedInpSequence.add(new XSDouble((Double.valueOf(nodeStrVal)).doubleValue()));
+               doubleItemCount++;
+            }
+            catch (NumberFormatException ex) {
+               throw new javax.xml.transform.TransformerException("FORG0006 : An xdm node's string value '" + 
+                                                                        nodeStrVal + "' cannot be cast to xs:double.", srcLocator); 
+            }
+         }
+      }
+      else if (xObjArg0 instanceof ResultSequence) {
+         ResultSequence resultSeq = (ResultSequence)xObjArg0;
+         
+         for (int idx = 0; idx < resultSeq.size(); idx++) {
+            XObject seqObj = resultSeq.item(idx);
+            if (seqObj instanceof XSUntypedAtomic) {
+               convetedInpSequence.add(new XSDouble(((XSUntypedAtomic)seqObj).
+                                                                        stringValue()));
+               doubleItemCount++;
+            }
+            else if (seqObj instanceof XSUntyped) {
+               convetedInpSequence.add(new XSDouble(((XSUntyped)seqObj).stringValue()));
+               doubleItemCount++;
+            }
+            else if (seqObj instanceof XSString) {
+               convetedInpSequence.add((XSString)seqObj);
+               strItemCount++;
+            }
+            else if (seqObj instanceof XString) {
+               String strValue = ((XString)seqObj).str();
+               convetedInpSequence.add(new XSString(strValue));
+               strItemCount++;
+            }
+            else if (seqObj instanceof XSNumericType) {
+               String strVal = ((XSNumericType)seqObj).stringValue();
+               convetedInpSequence.add(new XSDouble(strVal));
+               doubleItemCount++;
+            }
+            else if (seqObj instanceof XNumber) {
+               double doubleVal = ((XNumber)seqObj).num();
+               convetedInpSequence.add(new XSDouble(doubleVal));
+               doubleItemCount++;
+            }
+            else if (seqObj instanceof XSDate) {
+               convetedInpSequence.add((XSDate)seqObj);
+               dateItemCount++;
+            }
+         }
+         
+         // TO DO : to handle XML Schema types xs:duration (and its subtypes), xs:anyURI as
+         //         well, within function call fn:max's input sequence. 
+      }
+      else {
+         result = xObjArg0;  
+      }
+      
+      if (result == null) {
+         if ((doubleItemCount > 0) && (convetedInpSequence.size() == doubleItemCount)) {
+            result = getMaxValueFromXSDoubleSequence(convetedInpSequence);
+         }
+         else if ((strItemCount > 0) && (convetedInpSequence.size() == strItemCount)) {
+            String collationUri = getCollationUri(xctxt);
+            result = getMaxValueFromXSStringSequence(convetedInpSequence, collationUri, 
+                                                                                    xctxt);
+         }
+         else if ((dateItemCount > 0) && (convetedInpSequence.size() == dateItemCount)) {
+            result = getMaxValueFromXSDateSequence(convetedInpSequence);
+         }
+         else if ((xObjArg0 instanceof ResultSequence) && (((ResultSequence)xObjArg0).
+                                                                                  size() == 0)) {
+            // the result value is an empty sequence
+            result = new ResultSequence(); 
+         }
+         else {
+            throw new javax.xml.transform.TransformerException("FORG0006 : An input sequence processed by function fn:max, "
+                                                                     + "should have data values of same type for all the items of "
+                                                                     + "sequence (for e.g, all xs:double, all xs:string, all xs:date "
+                                                                     + "etc).", srcLocator); 
+         }
+      }
+      
+      if (result == null) {
+         // the result value is an empty sequence
+         result = new ResultSequence(); 
+      }
+      
+      return result;
+  }
+  
+  /**
+   * Check that the number of arguments passed to this function is correct.
+   *
+   * @param argNum The number of arguments that is being passed to the function.
+   *
+   * @throws WrongNumberArgsException
+   */
+  public void checkNumberArgs(int argNum) throws WrongNumberArgsException
+  {
+      if (!((argNum == 1) || (argNum == 2))) {
+         reportWrongNumberArgs();
+      }
+      else {
+         numOfArgs = argNum;   
+      }
+  }
+  
+  /**
+   * Constructs and throws a WrongNumberArgException with the appropriate
+   * message for this function object.
+   *
+   * @throws WrongNumberArgsException
+   */
+  protected void reportWrongNumberArgs() throws WrongNumberArgsException {
+     throw new WrongNumberArgsException(XSLMessages.createXPATHMessage(
+                                                                XPATHErrorResources.ER_ONE_OR_TWO, null)); //"1 or 2"
+  }
+  
+  /**
+   * Given a sequence of xdm XSDouble objects, find the XSDouble object
+   * that has maximum numeric value amongst the items of the provided 
+   * sequence.  
+   */
+  private XSDouble getMaxValueFromXSDoubleSequence(ResultSequence inpSeq) {
+     XSDouble result = new XSDouble(Double.NEGATIVE_INFINITY);
+     
+     double maxValue = ((XSDouble)(inpSeq.item(0))).doubleValue();
+         
+     for (int idx = 1; idx < inpSeq.size(); idx++) {
+        double nextVal = ((XSDouble)(inpSeq.item(idx))).doubleValue();
+        if (nextVal > maxValue) {
+           maxValue = nextVal;   
+        }
+     }
+         
+     result = new XSDouble(maxValue);
+     
+     return result;
+  }
+  
+  /**
+   * Given a sequence of xdm XSString objects, find the XSString object
+   * that is a maximum amongst the items of the provided sequence.   
+   */
+  private XSString getMaxValueFromXSStringSequence(ResultSequence inpSeq, 
+                                                            String collationUri, 
+                                                            XPathContext xctxt) throws javax.xml.transform.TransformerException {
+     XSString result = (XSString)(inpSeq.item(0));
+     
+     XPathCollationSupport xpathCollationSupport = xctxt.getXPathCollationSupport();
+     
+     for (int idx = 1; idx < inpSeq.size(); idx++) {
+        XSString nextVal = (XSString)(inpSeq.item(idx));
+        if (xpathCollationSupport.compareStringsUsingCollation(nextVal.stringValue(), result.stringValue(), 
+                                                                                                      collationUri) == 1) {
+           result = nextVal;  
+        }
+     }
+     
+     return result;
+  }
+  
+  /**
+   * Given a sequence of xdm XSDate objects, find the XSDate object
+   * that represents the latest date amongst the items of the provided 
+   * sequence.  
+   */
+  private XSDate getMaxValueFromXSDateSequence(ResultSequence inpSeq) {
+     XSDate result = (XSDate)(inpSeq.item(0));
+         
+     for (int idx = 1; idx < inpSeq.size(); idx++) {
+        XSDate nextVal = (XSDate)(inpSeq.item(idx));
+        if (nextVal.gt(result)) {
+           result = nextVal;   
+        }
+     }
+     
+     return result;
+  }
+  
+  /**
+   * Get the string comparison collation uri, for function call fn:max's evaluation.
+   */
+  private String getCollationUri(XPathContext xctxt) throws 
+                                                        javax.xml.transform.TransformerException {
+      
+      String collationUri = xctxt.getDefaultCollation();
+      
+      if (m_arg1 != null) {
+          XObject XObjArg1 = m_arg1.execute(xctxt);
+               
+          if ((XObjArg1 instanceof ResultSequence) && 
+                                                    (((ResultSequence)XObjArg1).size() == 0)) {
+             collationUri = xctxt.getDefaultCollation();   
+          }
+          else {
+             // a collation uri was, explicitly provided during the function call fn:max                  
+             collationUri = XslTransformEvaluationHelper.getStrVal(XObjArg1); 
+          }
+      }
+      
+      return collationUri;
+  }
+  
+}
diff --git a/src/org/apache/xpath/functions/FuncMin.java b/src/org/apache/xpath/functions/FuncMin.java
new file mode 100644
index 00000000..4c80bc6e
--- /dev/null
+++ b/src/org/apache/xpath/functions/FuncMin.java
@@ -0,0 +1,307 @@
+/*
+ * 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;
+
+import javax.xml.transform.SourceLocator;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xpath.XPathCollationSupport;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.ResultSequence;
+import org.apache.xpath.objects.XNodeSet;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XString;
+import org.apache.xpath.operations.Variable;
+import org.apache.xpath.res.XPATHErrorResources;
+import org.apache.xpath.xs.types.XSDate;
+import org.apache.xpath.xs.types.XSDouble;
+import org.apache.xpath.xs.types.XSNumericType;
+import org.apache.xpath.xs.types.XSString;
+import org.apache.xpath.xs.types.XSUntyped;
+import org.apache.xpath.xs.types.XSUntypedAtomic;
+
+/**
+ * Implementation of an XPath 3.1 function fn:min.
+ * 
+ * Ref : https://www.w3.org/TR/xpath-functions-31/#func-min
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class FuncMin extends FunctionMultiArgs
+{
+    
+  private static final long serialVersionUID = 3366369283941946933L;
+  
+  /**
+   * The number of arguments passed to the fn:min function 
+   * call.
+   */
+  private int numOfArgs = 0;
+
+  /**
+   * Execute the function. The function must return
+   * a valid object.
+   * @param xctxt The current execution context.
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {          
+      XObject result = null;
+      
+      SourceLocator srcLocator = xctxt.getSAXLocator();
+      
+      XObject xObjArg0 = null;
+      
+      ResultSequence convetedInpSequence = new ResultSequence(); 
+      
+      if (m_arg0 instanceof Variable) {
+         xObjArg0 = ((Variable)m_arg0).execute(xctxt);           
+      }
+      else {
+         xObjArg0 = m_arg0.execute(xctxt); 
+      }
+      
+      int doubleItemCount = 0;
+      int strItemCount = 0;
+      int dateItemCount = 0;
+      
+      if (xObjArg0 instanceof XNodeSet) {
+         // If for all the nodes of an input sequence, the node's string
+         // value can be cast to xs:double, we shall be able to process
+         // such a nodeset successfully, to be able to find a numeric
+         // minimum value from these nodes.
+         XNodeSet xsObjNodeSet = (XNodeSet)xObjArg0;
+         DTMIterator dtmIter = xsObjNodeSet.iterRaw();
+         
+         int nextNodeDtmHandle;
+         
+         while ((nextNodeDtmHandle = dtmIter.nextNode()) != DTM.NULL) {       
+            XNodeSet xdmNode = new XNodeSet(nextNodeDtmHandle, xctxt);
+            String nodeStrVal = xdmNode.str();
+            try {
+               convetedInpSequence.add(new XSDouble((Double.valueOf(nodeStrVal)).doubleValue()));
+               doubleItemCount++;
+            }
+            catch (NumberFormatException ex) {
+               throw new javax.xml.transform.TransformerException("FORG0006 : An xdm node's string value '" + 
+                                                                        nodeStrVal + "' cannot be cast to xs:double.", srcLocator); 
+            }
+         }
+      }
+      else if (xObjArg0 instanceof ResultSequence) {
+         ResultSequence resultSeq = (ResultSequence)xObjArg0;
+         
+         for (int idx = 0; idx < resultSeq.size(); idx++) {
+            XObject seqObj = resultSeq.item(idx);
+            if (seqObj instanceof XSUntypedAtomic) {
+               convetedInpSequence.add(new XSDouble(((XSUntypedAtomic)seqObj).
+                                                                        stringValue()));
+               doubleItemCount++;
+            }
+            else if (seqObj instanceof XSUntyped) {
+               convetedInpSequence.add(new XSDouble(((XSUntyped)seqObj).stringValue()));
+               doubleItemCount++;
+            }
+            else if (seqObj instanceof XSString) {
+               convetedInpSequence.add((XSString)seqObj);
+               strItemCount++;
+            }
+            else if (seqObj instanceof XString) {
+               String strValue = ((XString)seqObj).str();
+               convetedInpSequence.add(new XSString(strValue));
+               strItemCount++;
+            }
+            else if (seqObj instanceof XSNumericType) {
+               String strVal = ((XSNumericType)seqObj).stringValue();
+               convetedInpSequence.add(new XSDouble(strVal));
+               doubleItemCount++;
+            }
+            else if (seqObj instanceof XNumber) {
+               double doubleVal = ((XNumber)seqObj).num();
+               convetedInpSequence.add(new XSDouble(doubleVal));
+               doubleItemCount++;
+            }
+            else if (seqObj instanceof XSDate) {
+               convetedInpSequence.add((XSDate)seqObj);
+               dateItemCount++;
+            }
+         }
+         
+         // TO DO : to handle XML Schema types xs:duration (and its subtypes), xs:anyURI as
+         //         well, within function call fn:min's input sequence. 
+      }
+      else {
+         result = xObjArg0;  
+      }
+      
+      if (result == null) {
+         if ((doubleItemCount > 0) && (convetedInpSequence.size() == doubleItemCount)) {
+            result = getMinValueFromXSDoubleSequence(convetedInpSequence);
+         }
+         else if ((strItemCount > 0) && (convetedInpSequence.size() == strItemCount)) {
+            String collationUri = getCollationUri(xctxt);
+            result = getMinValueFromXSStringSequence(convetedInpSequence, collationUri, 
+                                                                                    xctxt);
+         }
+         else if ((dateItemCount > 0) && (convetedInpSequence.size() == dateItemCount)) {
+            result = getMinValueFromXSDateSequence(convetedInpSequence);
+         }
+         else if ((xObjArg0 instanceof ResultSequence) && (((ResultSequence)xObjArg0).
+                                                                                  size() == 0)) {
+            // the result value is an empty sequence
+            result = new ResultSequence(); 
+         }
+         else {
+            throw new javax.xml.transform.TransformerException("FORG0006 : An input sequence processed by function fn:min, "
+                                                                     + "should have data values of same type for all the items of "
+                                                                     + "sequence (for e.g, all xs:double, all xs:string, all xs:date "
+                                                                     + "etc).", srcLocator); 
+         }
+      }
+      
+      if (result == null) {
+         // the result value is an empty sequence
+         result = new ResultSequence(); 
+      }
+      
+      return result;
+  }
+  
+  /**
+   * Check that the number of arguments passed to this function is correct.
+   *
+   * @param argNum The number of arguments that is being passed to the function.
+   *
+   * @throws WrongNumberArgsException
+   */
+  public void checkNumberArgs(int argNum) throws WrongNumberArgsException
+  {
+      if (!((argNum == 1) || (argNum == 2))) {
+         reportWrongNumberArgs();
+      }
+      else {
+         numOfArgs = argNum;   
+      }
+  }
+  
+  /**
+   * Constructs and throws a WrongNumberArgException with the appropriate
+   * message for this function object.
+   *
+   * @throws WrongNumberArgsException
+   */
+  protected void reportWrongNumberArgs() throws WrongNumberArgsException {
+     throw new WrongNumberArgsException(XSLMessages.createXPATHMessage(
+                                                                XPATHErrorResources.ER_ONE_OR_TWO, null)); //"1 or 2"
+  }
+  
+  /**
+   * Given a sequence of xdm XSDouble objects, find the XSDouble object
+   * that has minimum numeric value amongst the items of the provided 
+   * sequence.  
+   */
+  private XSDouble getMinValueFromXSDoubleSequence(ResultSequence inpSeq) {
+     XSDouble result = new XSDouble(Double.NEGATIVE_INFINITY);
+     
+     double minValue = ((XSDouble)(inpSeq.item(0))).doubleValue();
+         
+     for (int idx = 1; idx < inpSeq.size(); idx++) {
+        double nextVal = ((XSDouble)(inpSeq.item(idx))).doubleValue();
+        if (nextVal < minValue) {
+           minValue = nextVal;   
+        }
+     }
+         
+     result = new XSDouble(minValue);
+     
+     return result;
+  }
+  
+  /**
+   * Given a sequence of xdm XSString objects, find the XSString object
+   * that is a minimum amongst the items of the provided sequence.   
+   */
+  private XSString getMinValueFromXSStringSequence(ResultSequence inpSeq, 
+                                                            String collationUri, 
+                                                            XPathContext xctxt) throws javax.xml.transform.TransformerException {
+     XSString result = (XSString)(inpSeq.item(0));
+     
+     XPathCollationSupport xpathCollationSupport = xctxt.getXPathCollationSupport();
+     
+     for (int idx = 1; idx < inpSeq.size(); idx++) {
+        XSString nextVal = (XSString)(inpSeq.item(idx));
+        if (xpathCollationSupport.compareStringsUsingCollation(nextVal.stringValue(), result.stringValue(), 
+                                                                                                      collationUri) == -1) {
+           result = nextVal;  
+        }
+     }
+     
+     return result;
+  }
+  
+  /**
+   * Given a sequence of xdm XSDate objects, find the XSDate object
+   * that represents the earliest date amongst the items of the 
+   * provided sequence.  
+   */
+  private XSDate getMinValueFromXSDateSequence(ResultSequence inpSeq) {
+     XSDate result = (XSDate)(inpSeq.item(0));
+         
+     for (int idx = 1; idx < inpSeq.size(); idx++) {
+        XSDate nextVal = (XSDate)(inpSeq.item(idx));
+        if (nextVal.lt(result)) {
+           result = nextVal;   
+        }
+     }
+     
+     return result;
+  }
+  
+  /**
+   * Get the string comparison collation uri, for function call fn:min's evaluation.
+   */
+  private String getCollationUri(XPathContext xctxt) throws 
+                                                        javax.xml.transform.TransformerException {
+      
+      String collationUri = xctxt.getDefaultCollation();
+      
+      if (m_arg1 != null) {
+          XObject XObjArg1 = m_arg1.execute(xctxt);
+               
+          if ((XObjArg1 instanceof ResultSequence) && 
+                                                    (((ResultSequence)XObjArg1).size() == 0)) {
+             collationUri = xctxt.getDefaultCollation();   
+          }
+          else {
+             // a collation uri was, explicitly provided during the function call fn:min                  
+             collationUri = XslTransformEvaluationHelper.getStrVal(XObjArg1); 
+          }
+      }
+      
+      return collationUri;
+  }
+  
+}
diff --git a/src/org/apache/xpath/xs/types/XSAnyAtomicType.java b/src/org/apache/xpath/xs/types/XSAnyAtomicType.java
index ff2f299e..7b1f377d 100644
--- a/src/org/apache/xpath/xs/types/XSAnyAtomicType.java
+++ b/src/org/apache/xpath/xs/types/XSAnyAtomicType.java
@@ -20,6 +20,8 @@
  */
 package org.apache.xpath.xs.types;
 
+import javax.xml.transform.TransformerException;
+
 import org.apache.xpath.objects.ResultSequence;
 
 /**
@@ -38,7 +40,7 @@ public abstract class XSAnyAtomicType extends XSAnySimpleType {
      * XDM objects with data types xs:boolean, xs:decimal etc.
      * 
      */
-    public abstract ResultSequence constructor(ResultSequence arg);
+    public abstract ResultSequence constructor(ResultSequence arg) throws TransformerException;
     
     /**
      * Get the datatype's name
diff --git a/src/org/apache/xpath/xs/types/XSCtrType.java b/src/org/apache/xpath/xs/types/XSCtrType.java
index c4e013ea..dbef2bc5 100644
--- a/src/org/apache/xpath/xs/types/XSCtrType.java
+++ b/src/org/apache/xpath/xs/types/XSCtrType.java
@@ -20,6 +20,8 @@
  */
 package org.apache.xpath.xs.types;
 
+import javax.xml.transform.TransformerException;
+
 import org.apache.xpath.objects.ResultSequence;
 
 /**
@@ -48,8 +50,10 @@ public abstract class XSCtrType extends XSAnyAtomicType {
 	 * @param arg    either an empty sequence, or an XML Schema atomic type
 	 * 
 	 * @return       the resulting ResultSequence
+	 * 
+     * @throws TransformerException 
 	 */
-	public abstract ResultSequence constructor(ResultSequence arg);
+	public abstract ResultSequence constructor(ResultSequence arg) throws TransformerException;
 
 	/**
 	 * Get the datatype's name.
diff --git a/src/org/apache/xpath/xs/types/XSDate.java b/src/org/apache/xpath/xs/types/XSDate.java
index 6700515d..a34ca85d 100644
--- a/src/org/apache/xpath/xs/types/XSDate.java
+++ b/src/org/apache/xpath/xs/types/XSDate.java
@@ -250,7 +250,7 @@ public class XSDate extends XSCalendarType {
     
     /*
      * Determine whether, this XSDate object is less that, the 
-     * XSDate object passed as an argument to this method. 
+     * XSDate object provided as an argument to this method. 
      */
     public boolean lt(XSDate xsDate) {
         boolean isDateBefore = false;
@@ -269,8 +269,8 @@ public class XSDate extends XSCalendarType {
     }
     
     /*
-     * Determine whether, this XSDate object is greater that, the 
-     * XSDate object passed as an argument to this method. 
+     * Determine whether, this XSDate object is greater than, the 
+     * XSDate object provided as an argument to this method. 
      */
     public boolean gt(XSDate xsDate) {
         boolean isDateAfter = false;
diff --git a/src/org/apache/xpath/xs/types/XSDouble.java b/src/org/apache/xpath/xs/types/XSDouble.java
index 7ab6467f..2cc8fff2 100644
--- a/src/org/apache/xpath/xs/types/XSDouble.java
+++ b/src/org/apache/xpath/xs/types/XSDouble.java
@@ -53,17 +53,18 @@ public class XSDouble extends XSNumericType {
 	/*
      * Class constructor.
      */
-	public XSDouble(String val) {
+	public XSDouble(String strVal) throws javax.xml.transform.TransformerException {
 		try {
-			if (val.equals("-INF")) {
+			if (strVal.equals("-INF")) {
 				_value = new Double(Double.NEGATIVE_INFINITY);
-			} else if (val.equals("INF")) {
+			} else if (strVal.equals("INF")) {
 				_value = new Double(Double.POSITIVE_INFINITY);
 			} else {
-				_value = new Double(val);
+				_value = new Double(strVal);
 			}
 		} catch (NumberFormatException ex) {
-			// to do
+			throw new javax.xml.transform.TransformerException("FORG0006 : The string value '" + 
+		                                                             strVal + "' cannot be cast to xs:double."); 
 		}
 	}
 
@@ -71,31 +72,33 @@ public class XSDouble extends XSNumericType {
 	 * Get a XSDouble object, corresponding to the string valued 
 	 * argument provided.
 	 * 
-	 * @param str   string value, to be parsed to an XSDouble object
+	 * @param strVal   string value, to be parsed to an XSDouble object
 	 * 
 	 * @return      an XSDouble object, corresponding to the string
 	 *              argument provided.
 	 */
-	public static XSDouble parseDouble(String str) {	    
+	public static XSDouble parseDouble(String strVal) throws javax.xml.transform.TransformerException {	    
 		try {
 			Double d1 = null;
 			
-			if (str.equals("INF")) {
+			if (strVal.equals("INF")) {
 				d1 = new Double(Double.POSITIVE_INFINITY);
-			} else if (str.equals("-INF")) {
+			} else if (strVal.equals("-INF")) {
 				d1 = new Double(Double.NEGATIVE_INFINITY);
 			} else {
-				d1 = new Double(str);
+				d1 = new Double(strVal);
 			}
 			
 			return new XSDouble(d1.doubleValue());			
 		} catch (NumberFormatException ex) {
-			return null;
+		    throw new javax.xml.transform.TransformerException("FORG0006 : The string value '" + 
+		                                                             strVal + "' cannot be cast to xs:double.");
 		}		
 	}
 	
 	@Override
-    public ResultSequence constructor(ResultSequence arg) {
+    public ResultSequence constructor(ResultSequence arg) throws 
+                                                              javax.xml.transform.TransformerException {
         ResultSequence resultSeq = new ResultSequence();
         
         if (arg.size() == 0) {
diff --git a/src/org/apache/xpath/xs/types/XSNumericType.java b/src/org/apache/xpath/xs/types/XSNumericType.java
index 502d2cff..f4d6863d 100644
--- a/src/org/apache/xpath/xs/types/XSNumericType.java
+++ b/src/org/apache/xpath/xs/types/XSNumericType.java
@@ -16,6 +16,8 @@
  */
 package org.apache.xpath.xs.types;
 
+import javax.xml.transform.TransformerException;
+
 import org.apache.xpath.objects.ResultSequence;
 
 /**
@@ -31,7 +33,7 @@ public class XSNumericType extends XSCtrType {
     private static final long serialVersionUID = 6842313858622701811L;
 
     @Override
-    public ResultSequence constructor(ResultSequence arg) {
+    public ResultSequence constructor(ResultSequence arg) throws TransformerException {
         return null;
     }
 
diff --git a/src/org/apache/xpath/xs/types/XSUntyped.java b/src/org/apache/xpath/xs/types/XSUntyped.java
index 07d115a5..c0f3257e 100644
--- a/src/org/apache/xpath/xs/types/XSUntyped.java
+++ b/src/org/apache/xpath/xs/types/XSUntyped.java
@@ -46,7 +46,7 @@ public class XSUntyped extends XSAnyType {
     }
 
     public String typeName() {
-        return "untypedAtomic";
+        return "untyped";
     }
     
     @Override
diff --git a/tests/fn_max/gold/test1.out b/tests/fn_max/gold/test1.out
new file mode 100644
index 00000000..2a02d747
--- /dev/null
+++ b/tests/fn_max/gold/test1.out
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>5</one>
+  <two>5</two>
+  <three>2100-01-01</three>
+  <four>c</four>
+  <five/>
+</result>
diff --git a/tests/fn_max/gold/test2.out b/tests/fn_max/gold/test2.out
new file mode 100644
index 00000000..d1378f0c
--- /dev/null
+++ b/tests/fn_max/gold/test2.out
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>7</one>
+  <two>10</two>
+</result>
diff --git a/tests/fn_max/test1.xsl b/tests/fn_max/test1.xsl
new file mode 100644
index 00000000..7279043e
--- /dev/null
+++ b/tests/fn_max/test1.xsl
@@ -0,0 +1,66 @@
+<?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"
+                exclude-result-prefixes="xs"
+                version="3.0">
+    
+    <!-- Author: mukulg@apache.org -->
+    
+    <!-- An XSLT stylesheet test, to test the XPath 3.1 fn:max() 
+         function.
+         
+         The examples of, function fn:max as used within this stylesheet,
+         are borrowed from XPath 3.1 F&O spec, with slight modifications.
+    --> 
+    
+    <xsl:output method="xml" indent="yes"/>
+    
+    <xsl:variable name="seq1" select="(3, 4, 5)"/>
+    
+    <xsl:variable name="seq2" select="(xs:integer(5), xs:float(5.0), xs:double(0))"/>
+    
+    <xsl:variable name="seq3" select="(current-date(), xs:date('2100-01-01'))"/>
+    
+    <xsl:variable name="seq4" select="('a', 'b', 'c')"/>
+    
+    <xsl:variable name="seq5" select="()"/>
+    
+    <xsl:template match="/">
+       <result>
+         <one>
+            <xsl:value-of select="max($seq1)"/> 
+         </one>
+         <two>
+            <xsl:value-of select="max($seq2)"/>
+         </two>
+         <three>
+	        <xsl:value-of select="max($seq3)"/>
+         </three>
+         <four>
+	        <xsl:value-of select="max($seq4)"/>
+         </four>
+         <five>
+	        <xsl:value-of select="max($seq5)"/>
+         </five>
+       </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>
\ No newline at end of file
diff --git a/tests/fn_max/test1_a.xml b/tests/fn_max/test1_a.xml
new file mode 100644
index 00000000..0bf910bc
--- /dev/null
+++ b/tests/fn_max/test1_a.xml
@@ -0,0 +1,8 @@
+<info>
+  <a>1</a>
+  <b>1.3</b>
+  <c>2</c>
+  <d>2.3</d>
+  <e>7</e>
+  <data val1="1" val2="2.3" val3="10"/>
+</info>
\ No newline at end of file
diff --git a/tests/fn_max/test2.xsl b/tests/fn_max/test2.xsl
new file mode 100644
index 00000000..c57d88cd
--- /dev/null
+++ b/tests/fn_max/test2.xsl
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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, to test the XPath 3.1 fn:max() 
+         function.
+         
+         This stylesheet, gets an input data to be transformed
+         from an XML external document.
+    -->                 
+    
+    <xsl:output method="xml" indent="yes"/>
+    
+    <xsl:template match="/info">
+       <result>
+         <one>
+           <xsl:value-of select="max(*[not(self::data)])"/> 
+         </one>
+         <two>
+           <xsl:value-of select="max(data/@*)"/>
+         </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>
\ No newline at end of file
diff --git a/tests/fn_min/gold/test1.out b/tests/fn_min/gold/test1.out
new file mode 100644
index 00000000..1b5427a4
--- /dev/null
+++ b/tests/fn_min/gold/test1.out
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>3</one>
+  <two>5</two>
+  <three>0</three>
+  <four>1900-01-01</four>
+  <five>a</five>
+</result>
diff --git a/tests/fn_min/gold/test2.out b/tests/fn_min/gold/test2.out
new file mode 100644
index 00000000..5bea7abb
--- /dev/null
+++ b/tests/fn_min/gold/test2.out
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>1.1</one>
+  <two>1.3</two>
+</result>
diff --git a/tests/fn_min/test1.xsl b/tests/fn_min/test1.xsl
new file mode 100644
index 00000000..3f70cb4d
--- /dev/null
+++ b/tests/fn_min/test1.xsl
@@ -0,0 +1,66 @@
+<?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"
+                exclude-result-prefixes="xs"
+                version="3.0">
+                
+    <!-- Author: mukulg@apache.org -->
+    
+    <!-- An XSLT stylesheet test, to test the XPath 3.1 fn:min() 
+         function.
+         
+         The examples of, function fn:min as used within this stylesheet,
+         are borrowed from XPath 3.1 F&O spec, with slight modifications.         
+    -->                
+    
+    <xsl:output method="xml" indent="yes"/>
+    
+    <xsl:variable name="seq1" select="(3, 4, 5)"/>
+    
+    <xsl:variable name="seq2" select="(xs:integer(5), xs:float(5), xs:double(10))"/>
+    
+    <xsl:variable name="seq3" select="(xs:float(0.0E0), xs:float(-0.0E0))"/>
+    
+    <xsl:variable name="seq4" select="(current-date(), xs:date('1900-01-01'))"/>
+    
+    <xsl:variable name="seq5" select="('a', 'b', 'c')"/>
+    
+    <xsl:template match="/">
+       <result>
+         <one>
+            <xsl:value-of select="min($seq1)"/> 
+         </one>
+         <two>
+            <xsl:value-of select="min($seq2)"/>
+         </two>
+         <three>
+	        <xsl:value-of select="min($seq3)"/>
+         </three>
+         <four>
+	        <xsl:value-of select="min($seq4)"/>
+         </four>
+         <five>
+	        <xsl:value-of select="min($seq5)"/>
+         </five>
+       </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>
\ No newline at end of file
diff --git a/tests/fn_min/test1_a.xml b/tests/fn_min/test1_a.xml
new file mode 100644
index 00000000..ecf69fec
--- /dev/null
+++ b/tests/fn_min/test1_a.xml
@@ -0,0 +1,8 @@
+<info>
+  <a>1.3</a>
+  <b>1.1</b>
+  <c>2</c>
+  <d>2.3</d>
+  <e>7</e>
+  <data val1="2.3" val2="1.3" val3="10"/>
+</info>
\ No newline at end of file
diff --git a/tests/fn_min/test2.xsl b/tests/fn_min/test2.xsl
new file mode 100644
index 00000000..2fced5a8
--- /dev/null
+++ b/tests/fn_min/test2.xsl
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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, to test the XPath 3.1 fn:min() 
+         function.
+         
+         This stylesheet, gets an input data to be transformed
+         from an XML external document.
+    -->                 
+    
+    <xsl:output method="xml" indent="yes"/>
+    
+    <xsl:template match="/info">
+       <result>
+         <one>
+           <xsl:value-of select="min(*[not(self::data)])"/> 
+         </one>
+         <two>
+           <xsl:value-of select="min(data/@*)"/>
+         </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>
\ No newline at end of file
diff --git a/tests/org/apache/xalan/xpath3/FnMaxTests.java b/tests/org/apache/xalan/xpath3/FnMaxTests.java
new file mode 100644
index 00000000..6f6f7720
--- /dev/null
+++ b/tests/org/apache/xalan/xpath3/FnMaxTests.java
@@ -0,0 +1,72 @@
+/*
+ * 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.xpath3;
+
+import org.apache.xalan.util.XslTransformTestsUtil;
+import org.apache.xalan.xslt3.XSLConstants;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * XPath 3.1 function fn:max test cases.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class FnMaxTests extends XslTransformTestsUtil {        
+    
+    private static final String XSL_TRANSFORM_INPUT_DIRPATH = XSLConstants.XSL_TRANSFORM_INPUT_DIRPATH_PREFIX 
+                                                                                                          + "fn_max/";
+    
+    private static final String XSL_TRANSFORM_GOLD_DIRPATH = XSLConstants.XSL_TRANSFORM_GOLD_DIRPATH_PREFIX 
+                                                                                                          + "fn_max/gold/";
+
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        // no op
+    }
+
+    @AfterClass
+    public static void tearDownAfterClass() throws Exception {        
+        xmlDocumentBuilderFactory = null;
+        xmlDocumentBuilder = null;
+        xslTransformerFactory = null;
+    }
+
+    @Test
+    public void xslFnMaxTest1() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test1.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslFnMaxTest2() {
+        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);
+    }
+
+}
diff --git a/tests/org/apache/xalan/xpath3/FnMinTests.java b/tests/org/apache/xalan/xpath3/FnMinTests.java
new file mode 100644
index 00000000..56881cb6
--- /dev/null
+++ b/tests/org/apache/xalan/xpath3/FnMinTests.java
@@ -0,0 +1,72 @@
+/*
+ * 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.xpath3;
+
+import org.apache.xalan.util.XslTransformTestsUtil;
+import org.apache.xalan.xslt3.XSLConstants;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * XPath 3.1 function fn:min test cases.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class FnMinTests extends XslTransformTestsUtil {        
+    
+    private static final String XSL_TRANSFORM_INPUT_DIRPATH = XSLConstants.XSL_TRANSFORM_INPUT_DIRPATH_PREFIX 
+                                                                                                           + "fn_min/";
+    
+    private static final String XSL_TRANSFORM_GOLD_DIRPATH = XSLConstants.XSL_TRANSFORM_GOLD_DIRPATH_PREFIX 
+                                                                                                           + "fn_min/gold/";
+
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        // no op
+    }
+
+    @AfterClass
+    public static void tearDownAfterClass() throws Exception {        
+        xmlDocumentBuilderFactory = null;
+        xmlDocumentBuilder = null;
+        xslTransformerFactory = null;
+    }
+
+    @Test
+    public void xslFnMinTest1() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test1.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslFnMinTest2() {
+        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);
+    }
+
+}
diff --git a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
index 660dee97..dcdc8216 100644
--- a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
+++ b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
@@ -30,6 +30,8 @@ import org.apache.xalan.xpath3.FnFoldRightTests;
 import org.apache.xalan.xpath3.FnForEachPairTests;
 import org.apache.xalan.xpath3.FnForEachTests;
 import org.apache.xalan.xpath3.FnIndexOfTests;
+import org.apache.xalan.xpath3.FnMaxTests;
+import org.apache.xalan.xpath3.FnMinTests;
 import org.apache.xalan.xpath3.FnParseXmlFragmentTests;
 import org.apache.xalan.xpath3.FnParseXmlTests;
 import org.apache.xalan.xpath3.FnSortTests;
@@ -88,7 +90,7 @@ import org.junit.runners.Suite.SuiteClasses;
                 FnFoldRightTests.class, FnForEachPairTests.class, FnSortTests.class, FnCodepointsToStringTests.class,
                 FnStringToCodepointsTests.class, FnCompareTests.class, FnCodepointEqualTests.class,
                 SequenceFunctionTests.class, FnParseXmlTests.class, FnParseXmlFragmentTests.class,
-                TemplateTests.class, FnAvgTests.class })
+                TemplateTests.class, FnAvgTests.class, FnMaxTests.class, FnMinTests.class })
 public class AllXsl3Tests {
 
 }


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