[prev in list] [next in list] [prev in thread] [next in thread] 

List:       xalan-cvs
Subject:    [xalan-java] branch xalan-j_xslt3.0 updated: committing implementation of xpath 3.1 value comparison
From:       mukulg () apache ! org
Date:       2023-06-24 11:31:43
Message-ID: 168760630300.3174893.4761162421174871137 () gitbox2-he-fi ! apache ! org
[Download RAW message or body]

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 76f6fb54 committing implementation of xpath 3.1 value comparison operator \
lt, and various other xalanj xslt 3.0 implementation improvements. also committing \
                few new related working test cases as well.
     new 65a35b0d Merge pull request #10 from mukulga/xalan-j_xslt3.0_mukul
76f6fb54 is described below

commit 76f6fb54cbcf0614ee9c501111d501ed8309f614
Author: Mukul Gandhi <gandhi.mukul@gmail.com>
AuthorDate: Sat Jun 24 16:46:43 2023 +0530

    committing implementation of xpath 3.1 value comparison operator lt, and various \
other xalanj xslt 3.0 implementation improvements. also committing few new related \
                working test cases as well.
---
 src/org/apache/xalan/templates/ElemValueOf.java    |  23 +-
 src/org/apache/xalan/templates/ElemVariable.java   |  20 +-
 .../xalan/templates/XSConstructorFunctionUtil.java |  15 +-
 src/org/apache/xpath/compiler/Compiler.java        |  16 +-
 src/org/apache/xpath/compiler/Keywords.java        |   3 +
 src/org/apache/xpath/compiler/OpCodes.java         |   9 +-
 src/org/apache/xpath/compiler/XPathParser.java     |  21 ++
 .../apache/xpath/functions/FuncCurrentDate.java    |   9 +-
 .../xpath/functions/FuncCurrentDateTime.java       |  11 +-
 src/org/apache/xpath/objects/XObject.java          |  81 +++++
 src/org/apache/xpath/operations/VcLt.java          |  54 ++++
 src/org/apache/xpath/xs/types/XSBoolean.java       |  20 ++
 src/org/apache/xpath/xs/types/XSCalendarType.java  |  23 +-
 src/org/apache/xpath/xs/types/XSDate.java          | 260 +++++++++++++--
 src/org/apache/xpath/xs/types/XSDateTime.java      | 351 +++++++++++----------
 src/org/apache/xpath/xs/types/XSDecimal.java       |   8 +
 src/org/apache/xpath/xs/types/XSDouble.java        |   8 +
 src/org/apache/xpath/xs/types/XSFloat.java         |   8 +
 src/org/apache/xpath/xs/types/XSInt.java           |   8 +
 src/org/apache/xpath/xs/types/XSInteger.java       |  26 +-
 src/org/apache/xpath/xs/types/XSLong.java          |   8 +
 src/org/apache/xpath/xs/types/XSTime.java          |  88 +++---
 .../apache/xalan/util/XslTransformTestsUtil.java   |  36 ++-
 .../apache/xalan/xpath3/ValueComparisonTests.java  |  35 +-
 tests/org/apache/xalan/xslt3/XSLConstants.java     |   4 +-
 tests/org/apache/xalan/xslt3/XslIterateTests.java  |  10 +
 tests/xpath_value_comparison/gold/test5.out        |  14 +
 tests/xpath_value_comparison/gold/test6.out        |  14 +
 tests/xpath_value_comparison/gold/test7.out        |  14 +
 tests/xpath_value_comparison/test1.xsl             |   5 +-
 tests/xpath_value_comparison/test1_b.xml           |  11 +
 tests/xpath_value_comparison/test2.xsl             |   5 +-
 tests/xpath_value_comparison/test3.xsl             |   5 +-
 tests/xpath_value_comparison/test4.xsl             |   5 +-
 .../{test3.xsl => test5.xsl}                       |  11 +-
 .../{test2.xsl => test6.xsl}                       |  13 +-
 tests/xpath_value_comparison/test7.xsl             |  63 ++++
 tests/xsl_iterate/gold/test13.out                  |   4 +
 tests/xsl_iterate/test13.xsl                       |  59 ++++
 39 files changed, 1056 insertions(+), 322 deletions(-)

diff --git a/src/org/apache/xalan/templates/ElemValueOf.java \
b/src/org/apache/xalan/templates/ElemValueOf.java index 4824efad..b54ff9da 100644
--- a/src/org/apache/xalan/templates/ElemValueOf.java
+++ b/src/org/apache/xalan/templates/ElemValueOf.java
@@ -293,16 +293,21 @@ public class ElemValueOf extends ElemTemplateElement {
                   if (expr instanceof FuncExtFunction) {                      
                       XObject evalResult = \
                XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn
                                                                                      \
                (xctxt, expr);
-                      String strValue = null;
-                      
-                      if (evalResult instanceof XSAnyType) {
-                          strValue = ((XSAnyType)evalResult).stringValue();    
+                      if (evalResult != null) {
+                          String strValue = null;
+                          
+                          if (evalResult instanceof XSAnyType) {
+                              strValue = ((XSAnyType)evalResult).stringValue();    
+                          }
+                          else {
+                              strValue = evalResult.str();  
+                          }
+    
+                          (new XString(strValue)).dispatchCharactersEvents(rth);
                       }
                       else {
-                          strValue = evalResult.str();  
+                          expr.executeCharsToContentHandler(xctxt, rth);   
                       }
-
-                      (new XString(strValue)).dispatchCharactersEvents(rth);
                   }
                   else if (expr instanceof Function) {
                       XObject evalResult = ((Function)expr).execute(xctxt);
@@ -364,8 +369,8 @@ public class ElemValueOf extends ElemTemplateElement {
     {
         throw new TransformerException(se);
     }
-    catch (RuntimeException re) {
-    	TransformerException te = new TransformerException(re);
+    catch (Exception ex) {
+    	TransformerException te = new TransformerException(ex);
     	te.setLocator(this);
     	throw te;
     }
diff --git a/src/org/apache/xalan/templates/ElemVariable.java \
b/src/org/apache/xalan/templates/ElemVariable.java index b2e3bf13..ba3d236f 100644
--- a/src/org/apache/xalan/templates/ElemVariable.java
+++ b/src/org/apache/xalan/templates/ElemVariable.java
@@ -279,7 +279,7 @@ public class ElemVariable extends ElemTemplateElement
                                                                  throws \
TransformerException  {
 
-    XObject var;
+    XObject var = null;
     
     final XPathContext xctxtOriginal = transformer.getXPathContext();
     
@@ -293,14 +293,18 @@ public class ElemVariable extends ElemTemplateElement
         if (selectExpression instanceof FuncExtFunction) {
             XObject evalResult = \
                XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn(xctxt, 
                                                                                      \
                selectExpression);
-            return evalResult;
+            if (evalResult != null) {
+                return evalResult;    
+            }
+            else {
+                var = m_selectPattern.execute(xctxt, sourceNode, this);    
+            }            
         }
         else if (selectExpression instanceof Function) {
             XObject evalResult = ((Function)selectExpression).execute(xctxt);        \
  if ((evalResult instanceof ResultSequence) || 
-                                                (evalResult instanceof XSAnyType)) {
-                var = evalResult;
-                return var; 
+                                                (evalResult instanceof XSAnyType)) { \
 +                return evalResult; 
             }
         }
         else if (selectExpression instanceof Operation) {
@@ -313,8 +317,10 @@ public class ElemVariable extends ElemTemplateElement
             
             return evalResult;
         }
-          
-        var = m_selectPattern.execute(xctxt, sourceNode, this);
+  
+        if (var == null) {
+           var = m_selectPattern.execute(xctxt, sourceNode, this);
+        }
 
         var.allowDetachToRelease(false);
 
diff --git a/src/org/apache/xalan/templates/XSConstructorFunctionUtil.java \
b/src/org/apache/xalan/templates/XSConstructorFunctionUtil.java index \
                8f4911ee..f06455f8 100644
--- a/src/org/apache/xalan/templates/XSConstructorFunctionUtil.java
+++ b/src/org/apache/xalan/templates/XSConstructorFunctionUtil.java
@@ -27,6 +27,7 @@ import org.apache.xpath.objects.ResultSequence;
 import org.apache.xpath.objects.XObject;
 import org.apache.xpath.operations.Operation;
 import org.apache.xpath.xs.types.XSBoolean;
+import org.apache.xpath.xs.types.XSDate;
 import org.apache.xpath.xs.types.XSDecimal;
 import org.apache.xpath.xs.types.XSDouble;
 import org.apache.xpath.xs.types.XSFloat;
@@ -37,7 +38,8 @@ import org.xml.sax.SAXException;
 
 /**
  * An utility class, to support evaluations of XPath 3.1 constructor 
- * functions, and few other XPath expression evaluations.
+ * functions (ref, https://www.w3.org/TR/xpath-functions-31/#constructor-functions), \
 + * and few other XPath expression evaluations.
  * 
  * @author Mukul Gandhi <mukulg@apache.org>
  * 
@@ -58,6 +60,7 @@ public class XSConstructorFunctionUtil {
             if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(funcExtFunction.getNamespace())) \
                {
                 // evaluate XPath 3.1 constructor function calls, corresponding to \
XML Schema   // built-in types.
+                
                 if ((Keywords.FUNC_XS_DECIMAL).equals(funcExtFunction.getFunctionName())) \
{                                ResultSequence argSequence = new ResultSequence();
                     for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
@@ -129,6 +132,16 @@ public class XSConstructorFunctionUtil {
                     ResultSequence rSeq = (new \
XSBoolean()).constructor(argSequence);  evalResult = rSeq.item(0);              
                 }
+                else if \
((Keywords.FUNC_XS_DATE).equals(funcExtFunction.getFunctionName())) {                 \
 +                    ResultSequence argSequence = new ResultSequence();
+                    for (int idx = 0; idx < funcExtFunction.getArgCount(); idx++) {
+                        XObject argVal = \
(funcExtFunction.getArg(idx)).execute(xctxt); +                        \
argSequence.add(XSDate.parseDate(argVal.str())); +                    }
+
+                    ResultSequence rSeq = (new XSDate()).constructor(argSequence); 
+                    evalResult = rSeq.item(0);              
+                }
             }
         }
         else if (expr instanceof Operation) {
diff --git a/src/org/apache/xpath/compiler/Compiler.java \
b/src/org/apache/xpath/compiler/Compiler.java index e16ce7cf..d3ce8db2 100644
--- a/src/org/apache/xpath/compiler/Compiler.java
+++ b/src/org/apache/xpath/compiler/Compiler.java
@@ -59,6 +59,7 @@ import org.apache.xpath.operations.Range;
 import org.apache.xpath.operations.UnaryOperation;
 import org.apache.xpath.operations.Variable;
 import org.apache.xpath.operations.VcEquals;
+import org.apache.xpath.operations.VcLt;
 import org.apache.xpath.operations.VcNotEquals;
 import org.apache.xpath.patterns.FunctionPattern;
 import org.apache.xpath.patterns.NodeTest;
@@ -137,6 +138,8 @@ public class Compiler extends OpMap
       expr = vcEquals(opPos); break;
     case OpCodes.OP_VC_NOT_EQUALS :
       expr = vcNotEquals(opPos); break;
+    case OpCodes.OP_VC_LT :
+      expr = vcLt(opPos); break;
     case OpCodes.OP_LTE :
       expr = lte(opPos); break;
     case OpCodes.OP_LT :
@@ -305,7 +308,7 @@ public class Compiler extends OpMap
   }
   
   /**
-   * Compile an 'eq' operation. 
+   * Compile an XPath 3.1 value comparison 'eq' operation. 
    */
   protected Expression vcEquals(int opPos) throws TransformerException
   {
@@ -313,7 +316,7 @@ public class Compiler extends OpMap
   }
   
   /**
-   * Compile an 'ne' operation. 
+   * Compile an XPath 3.1 value comparison 'ne' operation. 
    */
   protected Expression vcNotEquals(int opPos) throws TransformerException
   {
@@ -347,6 +350,15 @@ public class Compiler extends OpMap
   {
     return compileOperation(new Lt(), opPos);
   }
+  
+  /**
+   * Compile an XPath 3.1 value comparison 'lt' operation.
+   *  
+   */
+  protected Expression vcLt(int opPos) throws TransformerException
+  {
+    return compileOperation(new VcLt(), opPos);
+  }
 
   /**
    * Compile a '>=' operation.
diff --git a/src/org/apache/xpath/compiler/Keywords.java \
b/src/org/apache/xpath/compiler/Keywords.java index a5f4f4a3..5bfd7851 100644
--- a/src/org/apache/xpath/compiler/Keywords.java
+++ b/src/org/apache/xpath/compiler/Keywords.java
@@ -284,6 +284,9 @@ public class Keywords
   
   /** xs:int data type string. */
   public static final String FUNC_XS_INT = "int";
+  
+  /** xs:date data type string. */
+  public static final String FUNC_XS_DATE = "date";
 
   static
   {
diff --git a/src/org/apache/xpath/compiler/OpCodes.java \
b/src/org/apache/xpath/compiler/OpCodes.java index 799dd7fc..80d07447 100644
--- a/src/org/apache/xpath/compiler/OpCodes.java
+++ b/src/org/apache/xpath/compiler/OpCodes.java
@@ -647,8 +647,15 @@ public class OpCodes
    * @xsl.usage advanced
    */
   public static final int OP_VC_NOT_EQUALS = 56;
+  
+  /**
+   * For XPath 3.1 value comparison operator "lt".
+   * 
+   * @xsl.usage advanced
+   */
+  public static final int OP_VC_LT = 57;
 
   /** The next free ID. Please keep this up to date. */
-  private static final int NEXT_FREE_ID = 57;
+  private static final int NEXT_FREE_ID = 58;
   
 }
diff --git a/src/org/apache/xpath/compiler/XPathParser.java \
b/src/org/apache/xpath/compiler/XPathParser.java index 649a658e..b697beb4 100644
--- a/src/org/apache/xpath/compiler/XPathParser.java
+++ b/src/org/apache/xpath/compiler/XPathParser.java
@@ -851,6 +851,8 @@ public class XPathParser
    *
    * EqualityExpr  ::=  RelationalExpr
    * | EqualityExpr '=' RelationalExpr
+   * | EqualityExpr 'eq' RelationalExpr
+   * | EqualityExpr 'ne' RelationalExpr
    *
    *
    * @param addPos Position where expression is to be added, or -1 for append.
@@ -940,6 +942,10 @@ public class XPathParser
    * | RelationalExpr '<=' AdditiveExpr
    * | RelationalExpr '>=' AdditiveExpr
    * | RelationalExpr 'to' AdditiveExpr
+   * | RelationalExpr 'lt' AdditiveExpr
+   * | RelationalExpr 'le' AdditiveExpr
+   * | RelationalExpr 'gt' AdditiveExpr
+   * | RelationalExpr 'ge' AdditiveExpr
    *
    * @param addPos Position where expression is to be added, or -1 for append.
    *
@@ -1016,6 +1022,21 @@ public class XPathParser
             m_ops.getOp(addPos + op1 + 1) + op1);
           addPos += 2; 
       }
+      else if (tokenIs("lt"))
+      {
+          // support for XPath 3.1 value comparison operator "lt"
+          
+          nextToken();
+        
+          insertOp(addPos, 2, OpCodes.OP_VC_LT);
+
+          int op1 = m_ops.getOp(OpMap.MAPINDEX_LENGTH) - addPos;
+
+          addPos = RelationalExpr(addPos);
+          m_ops.setOp(addPos + OpMap.MAPINDEX_LENGTH,
+             m_ops.getOp(addPos + op1 + 1) + op1);
+          addPos += 2;
+      }
     }
 
     return addPos;
diff --git a/src/org/apache/xpath/functions/FuncCurrentDate.java \
b/src/org/apache/xpath/functions/FuncCurrentDate.java index 4b953dec..52166951 100644
--- a/src/org/apache/xpath/functions/FuncCurrentDate.java
+++ b/src/org/apache/xpath/functions/FuncCurrentDate.java
@@ -22,8 +22,6 @@ package org.apache.xpath.functions;
 
 import java.util.Vector;
 
-import javax.xml.transform.SourceLocator;
-
 import org.apache.xalan.res.XSLMessages;
 import org.apache.xpath.XPathContext;
 import org.apache.xpath.objects.XObject;
@@ -53,12 +51,11 @@ public class FuncCurrentDate extends Function {
    * @throws javax.xml.transform.TransformerException
    */
   public XObject execute(XPathContext xctxt) throws \
                javax.xml.transform.TransformerException {
-
-    SourceLocator srcLocator = xctxt.getSAXLocator();
     
-    XSDate currentDate = new XSDate(xctxt.getCurrentDateTime(), \
xctxt.getTimezone()); +    XSDate xsDate = new XSDate(xctxt.getCurrentDateTime(), \
xctxt.getTimezone()); +    xsDate.setPopulatedFromFnCurrentDate(true);
 
-    return (XObject)currentDate;
+    return (XObject)xsDate;
   }
 
   /**
diff --git a/src/org/apache/xpath/functions/FuncCurrentDateTime.java \
b/src/org/apache/xpath/functions/FuncCurrentDateTime.java index f15b59ab..ad26223e \
                100644
--- a/src/org/apache/xpath/functions/FuncCurrentDateTime.java
+++ b/src/org/apache/xpath/functions/FuncCurrentDateTime.java
@@ -22,8 +22,6 @@ package org.apache.xpath.functions;
 
 import java.util.Vector;
 
-import javax.xml.transform.SourceLocator;
-
 import org.apache.xalan.res.XSLMessages;
 import org.apache.xpath.XPathContext;
 import org.apache.xpath.objects.XObject;
@@ -54,7 +52,7 @@ public class FuncCurrentDateTime extends Function {
 
    private static final long serialVersionUID = -2032033071326423919L;
 
- /**
+   /**
    * Execute the function. The function must return a valid object.
    * 
    * @param xctxt The current execution context.
@@ -64,13 +62,10 @@ public class FuncCurrentDateTime extends Function {
    * @throws javax.xml.transform.TransformerException
    */
   public XObject execute(XPathContext xctxt) throws \
                javax.xml.transform.TransformerException {
-
-    SourceLocator srcLocator = xctxt.getSAXLocator();
     
-    XSDateTime currentDateTime = new XSDateTime(xctxt.getCurrentDateTime(), 
-                                                               xctxt.getTimezone());
+    XSDateTime xsDateTime = new XSDateTime(xctxt.getCurrentDateTime(), \
xctxt.getTimezone());  
-    return (XObject)currentDateTime;
+    return (XObject)xsDateTime;
   }
 
   /**
diff --git a/src/org/apache/xpath/objects/XObject.java \
b/src/org/apache/xpath/objects/XObject.java index f2374675..79c2415c 100644
--- a/src/org/apache/xpath/objects/XObject.java
+++ b/src/org/apache/xpath/objects/XObject.java
@@ -35,6 +35,7 @@ import org.apache.xpath.XPathException;
 import org.apache.xpath.XPathVisitor;
 import org.apache.xpath.res.XPATHErrorResources;
 import org.apache.xpath.xs.types.XSBoolean;
+import org.apache.xpath.xs.types.XSDate;
 import org.apache.xpath.xs.types.XSDecimal;
 import org.apache.xpath.xs.types.XSDouble;
 import org.apache.xpath.xs.types.XSFloat;
@@ -557,6 +558,80 @@ public class XObject extends Expression implements Serializable, \
Cloneable  
     return this.num() < obj2.num();
   }
+  
+  /**
+   * Tell if one object is less than an another one, using the rules 
+   * of value comparison operator "lt".
+   *
+   * @param obj2                Object to compare this to
+   * @param expressionOwner     this object is used, for error reporting 
+   *
+   * @return True if this object is less than the given object
+   *
+   * @throws javax.xml.transform.TransformerException
+   * 
+   * Notes : Currently, we don't implement following XPath 3.1 spec definitions for
+   *         value comparison operator "lt",
+   *         1) XPath 3.1 spec, requires atomizing the operands of XPath operator \
"lt", +   *            before applying operator "lt" to the operands.
+   *         2) If any of the operands of operator "lt", after atomization is an \
empty +   *            sequence, the result of operation "lt" should be an empty \
sequence.               +   */
+  public boolean vcLessThan(XObject obj2, ExpressionNode expressionOwner) throws 
+                                                                    \
javax.xml.transform.TransformerException { +       
+       if ((this instanceof XSDecimal) && (obj2 instanceof XSDecimal)) {
+          return ((XSDecimal)this).lt((XSDecimal)obj2);        
+       }
+       else if ((this instanceof XSFloat) && (obj2 instanceof XSFloat)) {
+          return ((XSFloat)this).lt((XSFloat)obj2);        
+       }
+       else if ((this instanceof XSDouble) && (obj2 instanceof XSDouble)) {
+          return ((XSDouble)this).lt((XSDouble)obj2);        
+       }
+       else if ((this instanceof XSBoolean) && (obj2 instanceof XSBoolean)) {
+          return ((XSBoolean)this).lt((XSBoolean)obj2);    
+       }
+       else if ((this instanceof XSInteger) && (obj2 instanceof XSInteger)) {
+          return ((XSInteger)this).lt((XSInteger)obj2);    
+       }
+       else if ((this instanceof XSLong) && (obj2 instanceof XSLong)) {
+          return ((XSLong)this).lt((XSLong)obj2);    
+       }
+       else if ((this instanceof XSInt) && (obj2 instanceof XSInt)) {
+          return ((XSInt)this).lt((XSInt)obj2);    
+       }
+       else if ((this instanceof XSDate) && (obj2 instanceof XSDate)) {
+           return ((XSDate)this).lt((XSDate)obj2);    
+       }
+       
+       boolean isOperandNodeSet1 = false;
+       boolean isOperandNodeSet2 = false;
+       
+       if (this.getType() == XObject.CLASS_NODESET) {       
+          isOperandNodeSet1 = true;
+          if ((((XNodeSet)this).getLength() > 1)) {
+              error(XPATHErrorResources.ER_EQ_OPERAND_CARDINALITY_ERROR, null, \
expressionOwner);     +          }
+       }
+       
+       if (obj2.getType() == XObject.CLASS_NODESET) {
+          isOperandNodeSet2 = true; 
+          if ((((XNodeSet)obj2).getLength() > 1)) {
+              error(XPATHErrorResources.ER_EQ_OPERAND_CARDINALITY_ERROR, null, \
expressionOwner);     +          }
+       }
+       
+       if (isOperandNodeSet1 || this instanceof XNumber) {
+           return this.num() < obj2.num();    
+       }    
+       else if (isOperandNodeSet2 || obj2 instanceof XNumber) {
+           return obj2.num() < this.num();    
+       }
+       
+       // revisit
+       return true;
+  }
 
   /**
    * Tell if one object is less than or equal to the other.
@@ -662,6 +737,9 @@ public class XObject extends Expression implements Serializable, \
Cloneable  else if ((this instanceof XSInt) && (obj2 instanceof XSInt)) {
        return ((XSInt)this).equals((XSInt)obj2);    
     }
+    else if ((this instanceof XSDate) && (obj2 instanceof XSDate)) {
+       return ((XSDate)this).equals((XSDate)obj2);    
+    }
         
     if (obj2.getType() == XObject.CLASS_NODESET) {
        return obj2.equals(this);
@@ -718,6 +796,9 @@ public class XObject extends Expression implements Serializable, \
Cloneable  else if ((this instanceof XSInt) && (obj2 instanceof XSInt)) {
        return ((XSInt)this).equals((XSInt)obj2);    
     }
+    else if ((this instanceof XSDate) && (obj2 instanceof XSDate)) {
+        return ((XSDate)this).equals((XSDate)obj2);    
+    }
     
     boolean isOperandNodeSet1 = false;
     boolean isOperandNodeSet2 = false;
diff --git a/src/org/apache/xpath/operations/VcLt.java \
b/src/org/apache/xpath/operations/VcLt.java new file mode 100644
index 00000000..0928099b
--- /dev/null
+++ b/src/org/apache/xpath/operations/VcLt.java
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+/*
+ * $Id$
+ */
+package org.apache.xpath.operations;
+
+import org.apache.xpath.objects.XBoolean;
+import org.apache.xpath.objects.XObject;
+
+/**
+ * The XPath 3.1 value comparison "lt" operation.
+ * 
+ * @author Mukul Gandhi <mukulg@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class VcLt extends Operation
+{
+
+   private static final long serialVersionUID = 3832212036565766741L;
+
+   /**
+   * Apply the operation to two operands, and return the result.
+   *
+   *
+   * @param left non-null reference to the evaluated left operand.
+   * @param right non-null reference to the evaluated right operand.
+   *
+   * @return non-null reference to the XObject that represents the result of the \
operation. +   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject operate(XObject left, XObject right) 
+                                                 throws \
javax.xml.transform.TransformerException +  {
+      return left.vcLessThan(right, getExpressionOwner()) ? XBoolean.S_TRUE : \
XBoolean.S_FALSE; +  }
+}
diff --git a/src/org/apache/xpath/xs/types/XSBoolean.java \
b/src/org/apache/xpath/xs/types/XSBoolean.java index 94589a87..84fa2670 100644
--- a/src/org/apache/xpath/xs/types/XSBoolean.java
+++ b/src/org/apache/xpath/xs/types/XSBoolean.java
@@ -103,6 +103,26 @@ public class XSBoolean extends XSCtrType {
         return _value == xsBoolean.value();  
     }
     
+    public boolean lt(XSBoolean xsBoolean) {
+        boolean resultVal = false;
+
+        if (!value() && xsBoolean.value()) {
+            resultVal = true;
+        }
+        
+        return resultVal;  
+    }
+    
+    public boolean gt(XSBoolean xsBoolean) {
+        boolean resultVal = false;
+
+        if (value() && !xsBoolean.value()) {
+            resultVal = true;
+        }
+        
+        return resultVal;  
+    }
+    
     /*
      * Check whether, a string value represents a boolean 
      * 'false' value.
diff --git a/src/org/apache/xpath/xs/types/XSCalendarType.java \
b/src/org/apache/xpath/xs/types/XSCalendarType.java index f3b954d7..8a2ecc09 100644
--- a/src/org/apache/xpath/xs/types/XSCalendarType.java
+++ b/src/org/apache/xpath/xs/types/XSCalendarType.java
@@ -15,13 +15,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id$
- */
 package org.apache.xpath.xs.types;
 
-import java.util.Calendar;
-
 /**
  * Base class for all calendar based classes.
  * 
@@ -31,22 +26,6 @@ import java.util.Calendar;
  */
 public abstract class XSCalendarType extends XSCtrType {
 
-	public Calendar normalizeCalendar(Calendar cal, XSDuration timezone) {
-		Calendar adjusted = (Calendar)cal.clone();
-		
-		if (timezone != null) {
-			int hours = timezone.hours();
-			int minutes = timezone.minutes();
-			if (!timezone.negative()) {
-				hours *= -1;
-				minutes *= -1;
-			}
-			adjusted.add(Calendar.HOUR_OF_DAY, hours);
-			adjusted.add(Calendar.MINUTE, minutes);
-		}
-		
-		return adjusted;
-		
-	}
+    private static final long serialVersionUID = -6546129697566314664L;
 	
 }
diff --git a/src/org/apache/xpath/xs/types/XSDate.java \
b/src/org/apache/xpath/xs/types/XSDate.java index a192954a..ec3a5ea2 100644
--- a/src/org/apache/xpath/xs/types/XSDate.java
+++ b/src/org/apache/xpath/xs/types/XSDate.java
@@ -18,7 +18,6 @@ package org.apache.xpath.xs.types;
 
 import java.util.Calendar;
 import java.util.GregorianCalendar;
-import java.util.TimeZone;
 
 import org.apache.xpath.objects.ResultSequence;
 
@@ -36,21 +35,27 @@ public class XSDate extends XSCalendarType {
     private static final String XS_DATE = "xs:date";
     
     private Calendar _calendar;
+    
     private boolean _timezoned;
+    
     private XSDuration _tz;
     
+    // stores the fact that, whether this XSDate object is constructed
+    // via XPath function call fn:current-date().
+    private boolean isPopulatedFromFnCurrentDate = false;
+    
     /**
      * Class constructor.
      * 
-     * Creates a new 'XSDate' instance, corresponding to the supplied 
-     * date and time.
+     * Creates a new XSDate object instance, corresponding to the provided 
+     * date and timezone.
      * 
      * @param cal     the java.util.Calendar representation of the date to be stored
      * 
-     * @param tz      the time zone of the date to be stored
+     * @param tz      the timezone of the date to be stored
      */
     public XSDate(Calendar cal, XSDuration tz) {
-        _calendar = cal;
+        _calendar = cal;        
         _tz = tz;
         
         if (tz == null) {
@@ -64,14 +69,74 @@ public class XSDate extends XSCalendarType {
     /*
      * Class constructor. 
      */
-    public XSDate() {
-        this(new GregorianCalendar(TimeZone.getTimeZone("GMT")), null);
-    }
+    public XSDate() {}
 
     @Override
     public ResultSequence constructor(ResultSequence arg) {
-        // TO DO
-        return null;
+        ResultSequence resultSeq = new ResultSequence();
+        
+        if (arg.size() == 0) {
+           return resultSeq;     
+        }
+        
+        XSAnyType xsAnyType = (XSAnyType)arg.item(0);
+        
+        XSDate xsDate = castToDate(xsAnyType);
+        
+        resultSeq.add(xsDate);
+
+        return resultSeq;        
+    }
+    
+    /**
+     * Parse a string representation of a date and construct an new XSDate object.
+     * 
+     * XML Schema 1.1 datatypes spec, provides following to be the valid string
+     * representation (which is an ISO 8601 date format) of xs:date typed value,
+     * 
+     * dateLexicalRep ::= yearFrag '-' monthFrag '-' dayFrag timezoneFrag? 
+     * 
+     * @param strVal     the string representation of the date
+     * @return           the XSDate representation of the provided string
+     */
+    public static XSDate parseDate(String strVal) {
+        String dateStr = "";
+        String timeStr = "T00:00:00.0";
+
+        int idx = strVal.indexOf('+', 1);
+        if (idx == -1) {
+            idx = strVal.indexOf('-', 1);
+            if (idx == -1) {
+                return null;
+            }
+            idx = strVal.indexOf('-', idx + 1);
+            if (idx == -1) {
+                return null;
+            }
+            idx = strVal.indexOf('-', idx + 1);
+        }
+        if (idx == -1) {
+            idx = strVal.indexOf('Z', 1);
+        }
+        if (idx != -1) {
+            dateStr = strVal.substring(0, idx);
+            dateStr += timeStr;
+            dateStr += strVal.substring(idx, strVal.length());
+        } else {
+            dateStr = strVal + timeStr;
+        }
+
+        XSDateTime dateTime = XSDateTime.parseDateTime(dateStr);        
+        if (dateTime == null) {
+           return null;
+        }
+
+        return new XSDate(dateTime.getCalendar(), dateTime.getTimezone());
+        
+    }
+    
+    public XSDuration getTimezone() {
+        return _tz;
     }
 
     @Override
@@ -87,9 +152,9 @@ public class XSDate extends XSCalendarType {
     /**
      * Get the Calendar representation of the date stored.
      * 
-     * @return    Calendar representation of the date stored
+     * @return    the java.util.Calendar representation of the date stored
      */
-    public Calendar calendar() {
+    public Calendar getCalendar() {
         return _calendar;
     }
     
@@ -103,55 +168,180 @@ public class XSDate extends XSCalendarType {
     }
     
     /**
-     * Check whether this date has an optional, timezone associated with it.
+     * Check whether this XSDate object has an, timezone associated with it.
      * 
-     * @return true    if there is a timezone associated with this date. false
-     *                 otherwise.
+     * @return true    if there is a timezone associated with this XSDate object.
+     *                 false otherwise.
      */
-    public boolean timezoned() {
+    public boolean isXsDateObjectTimezoned() {
         return _timezoned;
     }
 
     @Override
     public String stringValue() {
-        String ret = "";
+        String xsDateStrValue = "";
 
-        Calendar adjustFortimezone = calendar();
+        Calendar calendarObj = getCalendar();
 
-        if (adjustFortimezone.get(Calendar.ERA) == GregorianCalendar.BC) {
-            ret += "-";
+        if (calendarObj.get(Calendar.ERA) == GregorianCalendar.BC) {
+            xsDateStrValue += "-";
         }
 
-        ret += XSDateTime.pad_int(adjustFortimezone.get(Calendar.YEAR), 4);
+        xsDateStrValue += XSDateTime.padInt(calendarObj.get(Calendar.YEAR), 4);
 
-        ret += "-";
-        ret += XSDateTime.pad_int(month(), 2);
+        xsDateStrValue += "-";
+        xsDateStrValue += XSDateTime.padInt(month(), 2);
 
-        ret += "-";
-        ret += XSDateTime.pad_int(adjustFortimezone.get(Calendar.DAY_OF_MONTH), 2);
+        xsDateStrValue += "-";
+        xsDateStrValue += XSDateTime.padInt(calendarObj.get(Calendar.
+                                                                  DAY_OF_MONTH), 2);
 
-        if (timezoned()) {
+        if (isXsDateObjectTimezoned()) {
             int hrs = _tz.hours();
             int min = _tz.minutes();
             double secs = _tz.seconds();
             if (hrs == 0 && min == 0 && secs == 0) {
-                ret += "Z";
+                xsDateStrValue += "Z";
             } else {
-                String tZoneStr = "";
+                String timezoneStr = "";
                 if (_tz.negative()) {
-                    tZoneStr += "-";
+                    timezoneStr += "-";
                 } else {
-                    tZoneStr += "+";
+                    timezoneStr += "+";
                 }
-                tZoneStr += XSDateTime.pad_int(hrs, 2);
-                tZoneStr += ":";
-                tZoneStr += XSDateTime.pad_int(min, 2);
+                timezoneStr += XSDateTime.padInt(hrs, 2);
+                timezoneStr += ":";
+                timezoneStr += XSDateTime.padInt(min, 2);
 
-                ret += tZoneStr;
+                xsDateStrValue += timezoneStr;
             }
         }
 
-        return ret;
+        return xsDateStrValue;
+    }
+    
+    /*
+     * Determine whether, two XSDate objects are equal.
+     */
+    public boolean equals(XSDate xsDate) {
+        boolean isDateEqual = false;
+        
+        Calendar cal1 = getCalendar();
+        Calendar cal2 = xsDate.getCalendar();                
+        
+        int year1 = cal1.get(Calendar.YEAR);
+        int month1 = cal1.get(Calendar.MONTH);
+        int date1 = cal1.get(Calendar.DATE);
+        
+        int year2 = cal2.get(Calendar.YEAR);
+        int month2 = cal2.get(Calendar.MONTH);
+        int date2 = cal2.get(Calendar.DATE);
+        
+        XSDuration tz1 = getTimezone();
+        XSDuration tz2 = xsDate.getTimezone();
+        
+        isDateEqual = (((year1 + month1 + date1) == (year2 + month2 + date2)) && 
+                                     isTimezoneEqual(tz1, tz2, \
isPopulatedFromFnCurrentDate,  +                                                      \
xsDate.isPopulatedFromFnCurrentDate()));  +        
+        return isDateEqual; 
+    }
+    
+    /*
+     * Determine whether, this XSDate object is less that, the 
+     * XSDate object passed as an argument to this method. 
+     */
+    public boolean lt(XSDate xsDate) {
+        boolean isDateBefore = false;
+        
+        Calendar cal1 = getCalendar();
+        Calendar cal2 = xsDate.getCalendar();                
+        
+        int year1 = cal1.get(Calendar.YEAR);
+        int month1 = cal1.get(Calendar.MONTH);
+        int date1 = cal1.get(Calendar.DATE);
+        
+        int year2 = cal2.get(Calendar.YEAR);
+        int month2 = cal2.get(Calendar.MONTH);
+        int date2 = cal2.get(Calendar.DATE);
+        
+        isDateBefore = ((year1 + month1 + date1) < (year2 + month2 + date2)); 
+        
+        return isDateBefore;
+    }
+    
+    /*
+     * Determine whether, this XSDate object is greater that, the 
+     * XSDate object passed as an argument to this method. 
+     */
+    public boolean gt(XSDate xsDate) {
+        boolean isDateAfter = false;
+        
+        Calendar cal1 = getCalendar();
+        Calendar cal2 = xsDate.getCalendar();                
+        
+        int year1 = cal1.get(Calendar.YEAR);
+        int month1 = cal1.get(Calendar.MONTH);
+        int date1 = cal1.get(Calendar.DATE);
+        
+        int year2 = cal2.get(Calendar.YEAR);
+        int month2 = cal2.get(Calendar.MONTH);
+        int date2 = cal2.get(Calendar.DATE);
+        
+        isDateAfter = ((year1 + month1 + date1) > (year2 + month2 + date2)); 
+        
+        return isDateAfter; 
+    }
+
+    public boolean isPopulatedFromFnCurrentDate() {
+        return isPopulatedFromFnCurrentDate;
+    }
+
+    public void setPopulatedFromFnCurrentDate(boolean isPopulatedFromFnCurrentDate) \
{ +        this.isPopulatedFromFnCurrentDate = isPopulatedFromFnCurrentDate;
+    }
+    
+    /*
+     * Do a data type cast, of an XSAnyType argument passed to this method, to
+     * an XSDate object.
+     */
+    private XSDate castToDate(XSAnyType xsAnyType) {
+        if (xsAnyType instanceof XSDate) {
+            XSDate date = (XSDate) xsAnyType;
+            return new XSDate(date.getCalendar(), date.getTimezone());
+        }
+
+        if (xsAnyType instanceof XSDateTime) {
+            XSDateTime dateTime = (XSDateTime) xsAnyType;
+            return new XSDate(dateTime.getCalendar(), dateTime.getTimezone());
+        }
+
+        return parseDate(xsAnyType.stringValue());
+    }
+    
+    /*
+     * Determine whether, two timezone values (represented as XSDuration objects) 
+     * are equal. 
+     */
+    private boolean isTimezoneEqual(XSDuration tz1, XSDuration tz2, 
+                                          boolean isPopulatedFromFnCurrentDate1, 
+                                                          boolean \
isPopulatedFromFnCurrentDate2) { +         
+        boolean isTimezoneEqual = false;         
+        
+        if (tz1 == null && tz2 == null) {
+           isTimezoneEqual = true;
+        }
+        else if (tz1 != null && tz2 != null) {
+           isTimezoneEqual = ((tz1.hours() == tz2.hours()) && 
+                                                   (tz1.minutes() == tz2.minutes()) \
&&  +                                                           (tz1.negative() == \
tz2.negative())); +        }
+        else if (isPopulatedFromFnCurrentDate1 || isPopulatedFromFnCurrentDate2) {
+            isTimezoneEqual = true; 
+        }
+        
+        return isTimezoneEqual;
     }
 
 }
diff --git a/src/org/apache/xpath/xs/types/XSDateTime.java \
b/src/org/apache/xpath/xs/types/XSDateTime.java index 2a3204b8..e601ccf2 100644
--- a/src/org/apache/xpath/xs/types/XSDateTime.java
+++ b/src/org/apache/xpath/xs/types/XSDateTime.java
@@ -40,14 +40,16 @@ public class XSDateTime extends XSCalendarType {
     private static final String XS_DATE_TIME = "xs:dateTime";
     
     private Calendar _calendar;
+    
     private boolean _timezoned;
+    
     private XSDuration _tz;
     
     /**
      * Class constructor.
      * 
-     * Creates a new 'XSDateTime' instance, corresponding to the supplied 
-     * date and time.
+     * Creates a new XSDateTime object instance, corresponding to the provided 
+     * date, time and timezone.
      * 
      * @param cal     the java.util.Calendar representation of the date and 
      *                time to be stored
@@ -92,6 +94,14 @@ public class XSDateTime extends XSCalendarType {
         // TO DO
         return null;
     }
+    
+    public Calendar getCalendar() {
+        return _calendar;
+    }
+    
+    public XSDuration getTimezone() {
+        return _tz;
+    }
 
     @Override
     public String typeName() {
@@ -99,13 +109,13 @@ public class XSDateTime extends XSCalendarType {
     }
     
     /**
-     * Check to see if a character is numeric.
+     * Method to check, whether the provided character is numeric.
      * 
-     * @param x    character to be tested
+     * @param x    the character for which, this check is done
      * 
      * @return     true if the character is numeric. false otherwise.
      */
-    public static boolean is_digit(char x) {
+    public static boolean isDigit(char x) {
         if ('0' <= x && x <= '9') {
            return true;
         }
@@ -117,27 +127,29 @@ public class XSDateTime extends XSCalendarType {
      * Parse a string representation of a date and time, and retrieve the year,
      * month and day components from this string.
      * 
-     * @param  str    the String representation of the date (with optional timezone)
+     * @param  strVal    the string representation of the date (with an optional  
+     *                   timezone value)
      * 
-     * @return        an integer array of size 3. first element is the year, second 
-     *                element is the month, and third element is the day.
+     * @return           an integer array of size 3. first element of this array is \
the year,  +     *                   second element is the month, and third element \
                is the day.
      */
-    public static int[] parse_date(String str) {
+    public static int[] parseDate(String strVal) {
+        
+        int[] returnVal = new int[3];
+        
         int state = 0;
 
-        int[] ret = new int[3];
-
-        for (int i = 0; i < ret.length; i++) {
-            ret[i] = 0;
+        for (int i = 0; i < returnVal.length; i++) {
+            returnVal[i] = 0;
         }
 
         String token = "";
-        for (int i = 0; i < str.length(); i++) {
-            char x = str.charAt(i);
+        for (int i = 0; i < strVal.length(); i++) {
+            char x = strVal.charAt(i);
 
             switch (state) {
             case 0:
-                if (is_digit(x)) {
+                if (isDigit(x)) {
                     token += x;
                 } else if (x == '-') {
                     token += x;
@@ -167,11 +179,11 @@ public class XSDateTime extends XSCalendarType {
                         return null;
                     }
 
-                    ret[0] = Integer.parseInt(token);
+                    returnVal[0] = Integer.parseInt(token);
                     token = "";
                     state = 2;
                 } 
-                else if (is_digit(x)) {
+                else if (isDigit(x)) {
                     token += x;
                 }
                 else {
@@ -184,10 +196,10 @@ public class XSDateTime extends XSCalendarType {
                         return null;
                     }
 
-                    ret[1] = Integer.parseInt(token);
+                    returnVal[1] = Integer.parseInt(token);
                     token = "";
                     state = 3;
-                } else if (is_digit(x)) {
+                } else if (isDigit(x)) {
                     token += x;
                 }
                 else {
@@ -195,7 +207,7 @@ public class XSDateTime extends XSCalendarType {
                 }
                 break;
             case 3:
-                if (is_digit(x)) {
+                if (isDigit(x)) {
                     token += x;
                 }
                 else {
@@ -203,7 +215,7 @@ public class XSDateTime extends XSCalendarType {
                 }
                 break;
             default:
-                return ret;
+                return returnVal;
             }
         }
         
@@ -215,29 +227,31 @@ public class XSDateTime extends XSCalendarType {
             return null;
         }
 
-        ret[2] = Integer.parseInt(token);
+        returnVal[2] = Integer.parseInt(token);
 
-        return ret;
+        return returnVal;
     }
     
     /**
      * Parse a string representation of a date and time, and retrieve the hour,
-     * minute and seconds components from this string.
+     * minute and second components from this string.
      * 
-     * @param   str    the String representation of the date (with optional \
timezone) +     * @param   strVal    the string representation of the date (with an \
optional  +     *                    timezone value)
      * 
-     * @return         an integer array of size 3. first element is the hour, second \
                
-     *                 element is the minute, and third element is the seconds.
+     * @return            an integer array of size 3. first element is the hour, \
second  +     *                    element is the minute, and third element is the \
                seconds.
      */
-    public static double[] parse_time(String str) {
-        int state = 0; 
-
-        double[] ret = new double[3];
+    public static double[] parseTime(String strVal) {
+        
+        double[] returnVal = new double[3];
+        
+        int state = 0;
 
         String token = "";
 
-        for (int i = 0; i < str.length(); i++) {
-            char x = str.charAt(i);
+        for (int i = 0; i < strVal.length(); i++) {
+            char x = strVal.charAt(i);
 
             switch (state) {
             case 0:
@@ -246,10 +260,10 @@ public class XSDateTime extends XSCalendarType {
                     if (token.length() != 2) {
                         return null;
                     }
-                    ret[state] = Integer.parseInt(token);
+                    returnVal[state] = Integer.parseInt(token);
                     state++;
                     token = "";
-                } else if (is_digit(x)) {
+                } else if (isDigit(x)) {
                     token += x;
                 }
                 else {
@@ -257,7 +271,7 @@ public class XSDateTime extends XSCalendarType {
                 }
                 break;
             case 2:
-                if (is_digit(x)) {
+                if (isDigit(x)) {
                     token += x;
                     if (token.length() > 2) {
                         return null;
@@ -270,7 +284,7 @@ public class XSDateTime extends XSCalendarType {
                 }
                 break;
             case 3:
-                if (is_digit(x)) {
+                if (isDigit(x)) {
                     token += x;
                 }
                 else {
@@ -290,172 +304,179 @@ public class XSDateTime extends XSCalendarType {
             return null;
         }
 
-        ret[2] = Double.parseDouble(token);
+        returnVal[2] = Double.parseDouble(token);
 
-        if (ret[0] == 24.0) {
-            ret[0] = 00.0;
+        if (returnVal[0] == 24.0) {
+            returnVal[0] = 00.0;
         }
 
-        return ret;
+        return returnVal;
     }
     
     /**
-     * Parse a String representation of a date and time, and retrieve the
+     * Parse a string representation of a date and time, and retrieve the
      * timezone component from this string.
      * 
-     * @param  str   the String representation of the date (with optional timezone)
+     * @param  strVal   the string representation of the date (with an optional 
+     *                  timezone value)
      * 
-     * @return       an integer array of size 3. first element represents whether \
                the
-     *               timezone is ahead or behind GMT, second element is the hour
-     *               displacement, and third element is the minute displacement.
+     * @return          an integer array of size 3. first element represents whether \
the +     *                  timezone is ahead or behind GMT, second element is the \
hour +     *                  displacement, and third element is the minute \
                displacement.
      */
-    public static int[] parse_timezone(String str) {
-        int[] ret = new int[3];
+    public static int[] parseTimezone(String strVal) {
+        
+        int[] returnVal = new int[3];
 
-        for (int i = 0; i < ret.length; i++) {
-            ret[i] = 0;
+        for (int i = 0; i < returnVal.length; i++) {
+            returnVal[i] = 0;
         }
         
-        ret[0] = 1;
+        returnVal[0] = 1;
 
-        if (str.equals("Z")) {
-            return ret;
+        if (strVal.equals("Z")) {
+            return returnVal;
         }
 
-        if (str.startsWith("+")) {
-            ret[0] = 1;
+        if (strVal.startsWith("+")) {
+            returnVal[0] = 1;
         }
-        else if (str.startsWith("-")) {
-            ret[0] = -1;
+        else if (strVal.startsWith("-")) {
+            returnVal[0] = -1;
         }
         else {
             return null;
         }
 
-        str = str.substring(1, str.length());
+        strVal = strVal.substring(1, strVal.length());
 
-        if (str.length() != (2 + 1 + 2)) {
+        if (strVal.length() != (2 + 1 + 2)) {
             return null;
         }
 
         try {
-            ret[1] = Integer.parseInt(str.substring(0, 2));
-            ret[2] = Integer.parseInt(str.substring(3, 5));
+            returnVal[1] = Integer.parseInt(strVal.substring(0, 2));
+            returnVal[2] = Integer.parseInt(strVal.substring(3, 5));
 
-            if (ret[1] > 14) {
+            if (returnVal[1] > 14) {
                 return null;
             }
             
-            if (ret[2] > 59) {
+            if (returnVal[2] > 59) {
                 return null;
             }
 
-            return ret;
+            return returnVal;
         } catch (NumberFormatException ex) {
             return null;
         }
     }
     
     /**
-     * Parse a String representation of a date and time, and construct a new
+     * Parse a string representation of a date and time, and construct a new
      * XSDateTime object using that information.
      * 
-     * @param str    the String representation of the date (with optional timezone)
+     * @param strVal    the string representation of the date (with an optional 
+     *                  timezone value)
      * 
-     * @return       the XSDateTime representation of the date and time (with \
                optional
-     *               timezone)
+     * @return          the XSDateTime representation of the date and time (with an 
+     *                  optional timezone value)
      */
-    public static XSDateTime parseDateTime(String str) {
+    public static XSDateTime parseDateTime(String strVal) {
+        
+        XSDateTime xsDateTime = null;
 
-        int index = str.indexOf('T');
-        if (index == -1) {
+        int idx = strVal.indexOf('T');
+        if (idx == -1) {
             return null;
         }
 
-        String date = str.substring(0, index);
-        String time = str.substring(index + 1, str.length());
+        String date = strVal.substring(0, idx);
+        String time = strVal.substring(idx + 1, strVal.length());
         String timezone = null;
 
-        index = time.indexOf('+');
-        if (index == -1) {
-            index = time.indexOf('-');
+        idx = time.indexOf('+');
+        if (idx == -1) {
+            idx = time.indexOf('-');
         }
-        if (index == -1) {
-            index = time.indexOf('Z');
+        if (idx == -1) {
+            idx = time.indexOf('Z');
         }
-        if (index != -1) {
-            timezone = time.substring(index, time.length());
-            time = time.substring(0, index);
+        if (idx != -1) {
+            timezone = time.substring(idx, time.length());
+            time = time.substring(0, idx);
         }
 
-        int d[] = parse_date(date);
+        int d[] = parseDate(date);
         if (d == null) {
             return null;
         }
 
-        TimeZone UTC = TimeZone.getTimeZone("UTC");
-        GregorianCalendar cal = new GregorianCalendar(UTC);
+        TimeZone defaultTimezone = TimeZone.getDefault();
+        GregorianCalendar gregorianCalendarObj = new GregorianCalendar(
+                                                                 defaultTimezone);
 
         int year = d[0];
         if (year < 0) {
             year *= -1;
-            cal.set(Calendar.ERA, GregorianCalendar.BC);
+            gregorianCalendarObj.set(Calendar.ERA, GregorianCalendar.BC);
         } else {
-            cal.set(Calendar.ERA, GregorianCalendar.AD);
+            gregorianCalendarObj.set(Calendar.ERA, GregorianCalendar.AD);
         }
 
-        cal.set(Calendar.DAY_OF_MONTH, 2);
-        cal.set(Calendar.MONTH, 2);
+        gregorianCalendarObj.set(Calendar.DAY_OF_MONTH, 2);
+        gregorianCalendarObj.set(Calendar.MONTH, 2);
 
-        if (!set_item(cal, Calendar.YEAR, year)) {
+        if (!setItem(gregorianCalendarObj, Calendar.YEAR, year)) {
             return null;
         }
 
-        if (!set_item(cal, Calendar.MONTH, d[1] - 1)) {
+        if (!setItem(gregorianCalendarObj, Calendar.MONTH, d[1] - 1)) {
             return null;
         }
 
-        if (!set_item(cal, Calendar.DAY_OF_MONTH, d[2])) {
+        if (!setItem(gregorianCalendarObj, Calendar.DAY_OF_MONTH, d[2])) {
             return null;
         }
 
-        double t[] = parse_time(time);
+        double t[] = parseTime(time);
         if (t == null) {
             return null;
         }
 
-        if (!set_item(cal, Calendar.HOUR_OF_DAY, (int) t[0])) {
+        if (!setItem(gregorianCalendarObj, Calendar.HOUR_OF_DAY, (int) t[0])) {
             return null;
         }
 
-        if (!set_item(cal, Calendar.MINUTE, (int) t[1])) {
+        if (!setItem(gregorianCalendarObj, Calendar.MINUTE, (int) t[1])) {
             return null;
         }
 
-        if (!set_item(cal, Calendar.SECOND, (int) t[2])) {
+        if (!setItem(gregorianCalendarObj, Calendar.SECOND, (int) t[2])) {
             return null;
         }
 
         double ms = t[2] - ((int) t[2]);
         ms *= 1000;
-        if (!set_item(cal, Calendar.MILLISECOND, (int) ms)) {
+        if (!setItem(gregorianCalendarObj, Calendar.MILLISECOND, (int) ms)) {
             return null;
         }
 
         int tz[] = null;
-        XSDuration tzd = null;
+        XSDuration timezoneVal = null;
         if (timezone != null) {
-            tz = parse_timezone(timezone);
+            tz = parseTimezone(timezone);
 
             if (tz == null) {
                 return null;
             }
 
-            tzd = new XSDayTimeDuration(0, tz[1], tz[2], 0.0, tz[0] < 0);
-
+            timezoneVal = new XSDayTimeDuration(0, tz[1], tz[2], 0.0, tz[0] < 0);
         }
+        
+        xsDateTime = new XSDateTime(gregorianCalendarObj, timezoneVal); 
 
-        return new XSDateTime(cal, tzd);
+        return xsDateTime;
     }
 
     @Override
@@ -463,47 +484,53 @@ public class XSDateTime extends XSCalendarType {
         return XS_DATE_TIME;
     }
     
-    public Calendar calendar() {
-        return _calendar;
-    }
-    
-    public static String pad_int(int num, int len) {
-        String ret = "";
-        String snum = "" + num;
+    public static String padInt(int num, int len) {        
+        String returnVal = "";
+        
+        String numStr = "" + num;
 
-        int pad = len - snum.length();
+        int pad = len - numStr.length();
 
-        // sort out the negative
         if (num < 0) {
-            ret += "-";
-            snum = snum.substring(1, snum.length());
+            returnVal += "-";
+            numStr = numStr.substring(1, numStr.length());
             pad++;
         }
 
-        StringBuffer buf = new StringBuffer(ret);
+        StringBuffer strBuf = new StringBuffer(returnVal);
+        
         for (int i = 0; i < pad; i++) {
-            buf.append("0");
+            strBuf.append("0");
         }
-        buf.append(snum);
-        ret = buf.toString();
-        return ret;
+        
+        strBuf.append(numStr);
+        
+        returnVal = strBuf.toString();
+        
+        return returnVal;
     }
     
     public double second() {
-        double s = _calendar.get(Calendar.SECOND);
-        double ms = _calendar.get(Calendar.MILLISECOND);
+        double secondVal = _calendar.get(Calendar.SECOND);
+        double millisecVal = _calendar.get(Calendar.MILLISECOND);
 
-        ms /= 1000;
-        s += ms;
+        millisecVal /= 1000;
+        secondVal += millisecVal;
         
-        return s;
+        return secondVal;
     }
     
     public int month() {
         return _calendar.get(Calendar.MONTH) + 1;
     }
     
-    public boolean timezoned() {
+    /**
+     * Check whether this XSDateTime object has an, timezone associated with it.
+     * 
+     * @return true    if there is a timezone associated with this XSDateTime \
object. +     *                 false otherwise.
+     */
+    public boolean isXsDateTimeObjectTimezoned() {
         return _timezoned;
     }
 
@@ -511,59 +538,61 @@ public class XSDateTime extends XSCalendarType {
     public String stringValue() {
         String returnVal = "";
 
-        Calendar adjustFortimezone = calendar();
+        Calendar calendarVal = getCalendar();
 
-        if (adjustFortimezone.get(Calendar.ERA) == GregorianCalendar.BC) {
+        if (calendarVal.get(Calendar.ERA) == GregorianCalendar.BC) {
             returnVal += "-";
         }
 
-        returnVal += pad_int(adjustFortimezone.get(Calendar.YEAR), 4);
+        returnVal += padInt(calendarVal.get(Calendar.YEAR), 4);
 
         returnVal += "-";
-        returnVal += pad_int(month(), 2);
+        returnVal += padInt(month(), 2);
 
         returnVal += "-";
-        returnVal += pad_int(adjustFortimezone.get(Calendar.DAY_OF_MONTH), 2);
+        returnVal += padInt(calendarVal.get(Calendar.DAY_OF_MONTH), 2);
 
-        // time
         returnVal += "T";
 
-        returnVal += pad_int(adjustFortimezone.get(Calendar.HOUR_OF_DAY), 2);
+        returnVal += padInt(calendarVal.get(Calendar.HOUR_OF_DAY), 2);
 
         returnVal += ":";
-        returnVal += pad_int(adjustFortimezone.get(Calendar.MINUTE), 2);
+        returnVal += padInt(calendarVal.get(Calendar.MINUTE), 2);
 
         returnVal += ":";
-        int isecond = (int) second();
-        double sec = second();
+        int intSec = (int)second();
+        double doubleSec = second();
 
-        if ((sec - (isecond)) == 0.0)
-            returnVal += pad_int(isecond, 2);
+        if ((doubleSec - intSec) == 0.0) {
+           returnVal += padInt(intSec, 2);
+        }
         else {
-            if (sec < 10.0)
-                returnVal += "0" + sec;
-            else
-                returnVal += sec;
+            if (doubleSec < 10.0) {
+               returnVal += "0" + doubleSec;
+            }
+            else {
+               returnVal += doubleSec;
+            }
         }
 
-        if (timezoned()) {
+        if (isXsDateTimeObjectTimezoned()) {
             int hrs = _tz.hours();
             int min = _tz.minutes();
             double secs = _tz.seconds();
-            if (hrs == 0 && min == 0 && secs == 0) {
+            if ((hrs == 0) && (min == 0) && (secs == 0)) {
                 returnVal += "Z";
             } else {
-                String tZoneStr = "";
+                String timezoneStr = "";
                 if (_tz.negative()) {
-                    tZoneStr += "-";
+                    timezoneStr += "-";
                 } else {
-                    tZoneStr += "+";
+                    timezoneStr += "+";
                 }
-                tZoneStr += pad_int(hrs, 2);
-                tZoneStr += ":";
-                tZoneStr += pad_int(min, 2);
+                timezoneStr += padInt(hrs, 2);
+                timezoneStr += ":";
+                timezoneStr += padInt(min, 2);
 
-                returnVal += tZoneStr;
+                returnVal += timezoneStr;
             }
         }
 
@@ -571,26 +600,26 @@ public class XSDateTime extends XSCalendarType {
     }
     
     /**
-     * Set a particular field within the Calendar.
+     * Set a particular field within an java.util.Calendar object.
      * 
-     * @param cal     the Calendar object to set the field in
-     * @param item    the field to set
-     * @param val     the value to set the field to
+     * @param cal           the Calendar object to set the field in
+     * @param fieldId       the field to set
+     * @param fieldval      the value to set the field to
      * 
-     * @return        true if successfully set. false otherwise
+     * @return              true if successfully set. false otherwise
      */
-    private static boolean set_item(Calendar cal, int item, int val) {
-        int min = cal.getActualMinimum(item);
+    private static boolean setItem(Calendar cal, int fieldId, int fieldval) {
 
-        if (val < min)
+        if (fieldval < cal.getActualMinimum(fieldId)) {
             return false;
+        }
 
-        int max = cal.getActualMaximum(item);
-
-        if (val > max)
+        if (fieldval > cal.getActualMaximum(fieldId)) {
             return false;
+        }
 
-        cal.set(item, val);
+        cal.set(fieldId, fieldval);
+        
         return true;
     }
 
diff --git a/src/org/apache/xpath/xs/types/XSDecimal.java \
b/src/org/apache/xpath/xs/types/XSDecimal.java index b020bb09..980a9519 100644
--- a/src/org/apache/xpath/xs/types/XSDecimal.java
+++ b/src/org/apache/xpath/xs/types/XSDecimal.java
@@ -137,6 +137,14 @@ public class XSDecimal extends XSNumericType {
         return _value.equals(xsDecimal.getValue()); 
     }
     
+    public boolean lt(XSDecimal xsDecimal) {
+        return (_value.compareTo(xsDecimal.getValue()) == -1);
+    }
+    
+    public boolean gt(XSDecimal xsDecimal) {
+        return (_value.compareTo(xsDecimal.getValue()) == 1);
+    }
+    
     /*
      * Cast an object of type XSAnyType, to an object of type 
      * XSDecimal.  
diff --git a/src/org/apache/xpath/xs/types/XSDouble.java \
b/src/org/apache/xpath/xs/types/XSDouble.java index 1d39f653..7ab6467f 100644
--- a/src/org/apache/xpath/xs/types/XSDouble.java
+++ b/src/org/apache/xpath/xs/types/XSDouble.java
@@ -193,4 +193,12 @@ public class XSDouble extends XSNumericType {
         return _value.equals(xsDouble.doubleValue()); 
     }
     
+    public boolean lt(XSDouble xsDouble) {
+        return doubleValue() < xsDouble.doubleValue(); 
+    }
+    
+    public boolean gt(XSDouble xsDouble) {
+        return doubleValue() > xsDouble.doubleValue(); 
+    }
+    
 }
diff --git a/src/org/apache/xpath/xs/types/XSFloat.java \
b/src/org/apache/xpath/xs/types/XSFloat.java index c71f03f4..fb935958 100644
--- a/src/org/apache/xpath/xs/types/XSFloat.java
+++ b/src/org/apache/xpath/xs/types/XSFloat.java
@@ -187,4 +187,12 @@ public class XSFloat extends XSNumericType {
         return _value.equals(xsFloat.floatValue()); 
     }
 	
+	public boolean lt(XSFloat xsFloat) {
+	    return floatValue() < xsFloat.floatValue(); 
+    }
+	
+	public boolean gt(XSFloat xsFloat) {
+	    return floatValue() > xsFloat.floatValue(); 
+    }
+	
 }
diff --git a/src/org/apache/xpath/xs/types/XSInt.java \
b/src/org/apache/xpath/xs/types/XSInt.java index 72249bf6..7f93a0ac 100644
--- a/src/org/apache/xpath/xs/types/XSInt.java
+++ b/src/org/apache/xpath/xs/types/XSInt.java
@@ -98,4 +98,12 @@ public class XSInt extends XSLong {
         return _value.equals(xsInt.intValue()); 
     }
 	
+	public boolean lt(XSInt xsInt) {
+	    return _value.compareTo(xsInt.intValue()) < 0; 
+    }
+	
+	public boolean gt(XSInt xsInt) {
+	    return _value.compareTo(xsInt.intValue()) > 0; 
+    }
+	
 }
diff --git a/src/org/apache/xpath/xs/types/XSInteger.java \
b/src/org/apache/xpath/xs/types/XSInteger.java index 0d207894..8232b066 100644
--- a/src/org/apache/xpath/xs/types/XSInteger.java
+++ b/src/org/apache/xpath/xs/types/XSInteger.java
@@ -128,12 +128,24 @@ public class XSInteger extends XSDecimal {
 		_value = val;
 	}
 	
+	public boolean equals(XSInteger xsInteger) {
+        return _value.equals(xsInteger.intValue()); 
+    }
+	
+	public boolean lt(XSInteger xsInteger) {
+	    return (intValue()).compareTo(xsInteger.intValue()) < 0; 
+    }
+	
+	public boolean gt(XSInteger xsInteger) {
+	    return (intValue()).compareTo(xsInteger.intValue()) > 0; 
+    }
+	
 	/*
-	 * Do a datatype cast, of a generic typed XML Schema value,
-	 * to a java.math.BigInteger value. 
-	 */
-	private BigInteger castToInteger(XSAnyType xsAnyType) {
-	    
+     * Cast an object of type XSAnyType, to an object of type 
+     * java.math.BigInteger.  
+     */
+    private BigInteger castToInteger(XSAnyType xsAnyType) {
+        
         if (xsAnyType instanceof XSBoolean) {
             if ((xsAnyType.stringValue()).equals("true")) {
                 return BigInteger.ONE;
@@ -152,9 +164,5 @@ public class XSInteger extends XSDecimal {
         
         return new BigInteger(xsAnyType.stringValue());
     }
-	
-	public boolean equals(XSInteger xsInteger) {
-        return _value.equals(xsInteger.intValue()); 
-    }
 
 }
diff --git a/src/org/apache/xpath/xs/types/XSLong.java \
b/src/org/apache/xpath/xs/types/XSLong.java index 482bfb1d..e1e7032d 100644
--- a/src/org/apache/xpath/xs/types/XSLong.java
+++ b/src/org/apache/xpath/xs/types/XSLong.java
@@ -96,5 +96,13 @@ public class XSLong extends XSInteger {
 	public boolean equals(XSLong xsLong) {
         return _value.equals(xsLong.intValue()); 
     }
+	
+	public boolean lt(XSLong xsLong) {
+	    return _value.compareTo(xsLong.intValue()) < 0; 
+    }
+	
+	public boolean gt(XSLong xsLong) {
+	    return _value.compareTo(xsLong.intValue()) > 0; 
+    }
 
 }
diff --git a/src/org/apache/xpath/xs/types/XSTime.java \
b/src/org/apache/xpath/xs/types/XSTime.java index 6289d915..e5c46d5b 100644
--- a/src/org/apache/xpath/xs/types/XSTime.java
+++ b/src/org/apache/xpath/xs/types/XSTime.java
@@ -36,16 +36,20 @@ public class XSTime extends XSCalendarType {
     private static final String XS_TIME = "xs:time";
     
     private Calendar _calendar;
+    
     private boolean _timezoned;
+    
     private XSDuration _tz;
     
     /**
      * Class constructor.
      * 
-     * Initializes this object, to the supplied time and timezone.
+     * Construct an XSTime object, with the provided time and timezone 
+     * values.
      * 
-     * @param cal   Calendar representation of the time to be stored
-     * @param tz    the timezone (possibly null) associated with this time
+     * @param cal   the java.util.Calendar representation of the time to be stored
+     * @param tz    the timezone (this could be possibly null) associated with this 
+     *              XSTime object.
      */
     public XSTime(Calendar cal, XSDuration tz) {
         _calendar = cal;
@@ -60,10 +64,12 @@ public class XSTime extends XSCalendarType {
     }
 
     /**
-     * Initialises to the current time
+     * Class constructor.
+     * 
+     * Construct an XSTime object, and initialize it to the current time.
      */
     public XSTime() {
-        this (new GregorianCalendar(TimeZone.getTimeZone("GMT")), null);
+        this (new GregorianCalendar(TimeZone.getDefault()), null);
     }
 
     @Override
@@ -75,7 +81,7 @@ public class XSTime extends XSCalendarType {
     /**
      * Get the datatype's name.
      * 
-     * @return   "time" which is the datatype's name
+     * @return   "time" which is this datatype's name
      */
     @Override
     public String typeName() {
@@ -85,7 +91,7 @@ public class XSTime extends XSCalendarType {
     /**
      * Get the datatype's full name.
      * 
-     * @return   "xs:time" which is the datatype's full name
+     * @return   "xs:time" which is this datatype's full name
      */
     @Override
     public String stringType() {
@@ -93,8 +99,8 @@ public class XSTime extends XSCalendarType {
     }
     
     /**
-     * Get a java.util.Calendar representation of time stored, 
-     * within this object.
+     * Get a java.util.Calendar representation of an time value stored, 
+     * within this XSTime object.
      * 
      * @return    Calendar representation of the time stored
      */
@@ -103,63 +109,59 @@ public class XSTime extends XSCalendarType {
     }
     
     /**
-     * Get the seconds stored as an integer, within this object.
+     * Get the seconds value as an integer stored within this 
+     * XSTime object.
      * 
-     * @return    the second stored
+     * @return    the seconds value stored
      */
     public double second() {
-        double s = _calendar.get(Calendar.SECOND);
-        double ms = _calendar.get(Calendar.MILLISECOND);
+        double secondVal = _calendar.get(Calendar.SECOND);
+        double millisecVal = _calendar.get(Calendar.MILLISECOND);
 
-        ms /= 1000;
-        s += ms;
+        millisecVal /= 1000;
+        secondVal += millisecVal;
         
-        return s;
+        return secondVal;
     }
     
     /**
-     * Check whether the time component stored within this object, 
-     * has a timezone associated with it.
+     * Check whether this XSTime object has an, timezone associated with it.
      * 
-     * @return    true if the time has a timezone associated. false otherwise.
+     * @return true    if there is a timezone associated with this XSTime object.
+     *                 false otherwise.
      */
-    public boolean timezoned() {
+    public boolean isXsTimeObjectTimezoned() {
         return _timezoned;
     }
 
-    /**
-     * Get a String representation of the time stored.
-     * 
-     * @return   String representation of the time stored
-     */
     @Override
     public String stringValue() {
         String returnVal = "";
         
-        Calendar adjustFortimezone = calendar();
-        returnVal += XSDateTime.pad_int(adjustFortimezone.get(Calendar.HOUR_OF_DAY), \
2); +        Calendar calendarVal = calendar();
+        returnVal += XSDateTime.padInt(calendarVal.get(Calendar.HOUR_OF_DAY), 2);
         
         returnVal += ":";
-        returnVal += XSDateTime.pad_int(adjustFortimezone.get(Calendar.MINUTE), 2);
+        returnVal += XSDateTime.padInt(calendarVal.get(Calendar.MINUTE), 2);
         
 
         returnVal += ":";
-        int isecond = (int) second();
-        double sec = second();
+        int intSec = (int) second();
+        double doubleSec = second();
 
-        if ((sec - (isecond)) == 0.0) {
-            returnVal += XSDateTime.pad_int(isecond, 2);
+        if ((doubleSec - intSec) == 0.0) {
+            returnVal += XSDateTime.padInt(intSec, 2);
         }
         else {
-            if (sec < 10.0) {
-               returnVal += "0" + sec;
+            if (doubleSec < 10.0) {
+               returnVal += "0" + doubleSec;
             }
             else {
-               returnVal += sec;
+               returnVal += doubleSec;
             }
         }
 
-        if (timezoned()) {
+        if (isXsTimeObjectTimezoned()) {
             int hrs = _tz.hours();
             int min = _tz.minutes();
             double secs = _tz.seconds();
@@ -167,18 +169,18 @@ public class XSTime extends XSCalendarType {
                returnVal += "Z";
             }
             else {
-               String tZoneStr = "";
+               String timezoneStr = "";
                if (_tz.negative()) {
-                  tZoneStr += "-";  
+                  timezoneStr += "-";  
                }
                else {
-                  tZoneStr += "+"; 
+                  timezoneStr += "+"; 
                }
-               tZoneStr += XSDateTime.pad_int(hrs, 2);  
-               tZoneStr += ":";
-               tZoneStr += XSDateTime.pad_int(min, 2);
+               timezoneStr += XSDateTime.padInt(hrs, 2);  
+               timezoneStr += ":";
+               timezoneStr += XSDateTime.padInt(min, 2);
               
-               returnVal += tZoneStr;
+               returnVal += timezoneStr;
             }
          }
 
diff --git a/tests/org/apache/xalan/util/XslTransformTestsUtil.java \
b/tests/org/apache/xalan/util/XslTransformTestsUtil.java index b7302aa3..41ee006f \
                100644
--- a/tests/org/apache/xalan/util/XslTransformTestsUtil.java
+++ b/tests/org/apache/xalan/util/XslTransformTestsUtil.java
@@ -19,6 +19,8 @@ package org.apache.xalan.util;
 import java.io.StringWriter;
 import java.nio.file.Files;
 import java.nio.file.Paths;
+import java.time.OffsetDateTime;
+import java.util.Date;
 import java.util.List;
 
 import javax.xml.parsers.DocumentBuilder;
@@ -37,7 +39,7 @@ import org.xml.sax.InputSource;
 import junit.framework.Assert;
 
 /**
- * A class providing, common services to this junit test suite.
+ * A class providing, common services to this JUnit test suite.
  * 
  * @author Mukul Gandhi <mukulg@apache.org>
  * 
@@ -89,15 +91,41 @@ public class XslTransformTestsUtil {
                    // the test has passed
                    return;
                }
+               else {
+                   // the test has failed
+                   Assert.fail();  
+               }
            }
+           else {
+              byte[] goldFileBytes = Files.readAllBytes(Paths.get(goldFilePath));
            
-           byte[] goldFileBytes = Files.readAllBytes(Paths.get(goldFilePath));
-           
-           Assert.assertEquals(new String(goldFileBytes), \
resultStrWriter.toString());           +              Assert.assertEquals(new \
String(goldFileBytes), resultStrWriter.toString()); +           }
         }
         catch (Exception ex) {
             Assert.fail();    
         }
      }
     
+     public static Date getCurrentDate() {
+         Date currentDate = new Date();
+       
+         return currentDate;
+     }
+    
+     public static String getDefaultTimezoneOffsetStr() {
+         String timeZoneoffsetStr = null;
+        
+         String dateStr = (OffsetDateTime.now()).toString();
+         if (dateStr.endsWith("Z")) {
+             timeZoneoffsetStr = "Z";   
+         }
+         else {
+             int dateStrLength = dateStr.length();
+             timeZoneoffsetStr = dateStr.substring(dateStrLength - 6, \
dateStrLength);  +         }
+        
+         return timeZoneoffsetStr;
+     }
+    
 }
diff --git a/tests/org/apache/xalan/xpath3/ValueComparisonTests.java \
b/tests/org/apache/xalan/xpath3/ValueComparisonTests.java index e6638fc6..2d639ce2 \
                100644
--- a/tests/org/apache/xalan/xpath3/ValueComparisonTests.java
+++ b/tests/org/apache/xalan/xpath3/ValueComparisonTests.java
@@ -24,7 +24,7 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 
 /**
- * XPath test cases, for value comparison operators 
+ * XPath 3.1 test cases, for value comparison operators 
  * eq, ne, lt, le, gt, ge.
  * 
  * @author Mukul Gandhi <mukulg@apache.org>
@@ -87,8 +87,37 @@ public class ValueComparisonTests extends XslTransformTestsUtil {
         
         String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test4.out";              \
  
-        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, 
-                                                                        new \
XslTestsErrorHandler()); +        runXslTransformAndAssertOutput(xmlFilePath, \
xslFilePath, goldFilePath, null); +    }
+    
+    @Test
+    public void xslValueComparison5() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test5.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test5.out";              \
 +        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, \
null); +    }
+    
+    @Test
+    public void xslValueComparison6() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_b.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test6.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test6.out";              \
 +        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, \
null); +    }
+    
+    @Test
+    public void xslValueComparison7() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test7.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test7.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test7.out";              \
 +        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, \
null);  }
 
 }
diff --git a/tests/org/apache/xalan/xslt3/XSLConstants.java \
b/tests/org/apache/xalan/xslt3/XSLConstants.java index c85a98db..ccaf7dab 100644
--- a/tests/org/apache/xalan/xslt3/XSLConstants.java
+++ b/tests/org/apache/xalan/xslt3/XSLConstants.java
@@ -36,8 +36,8 @@ public class XSLConstants {
     // the values of following, two variables are host specific where this test \
suite shall be run. the values of  // following two variables may be modified, \
accordingly.  
-    public static final String XSL_TRANSFORM_INPUT_DIRPATH_PREFIX = \
"file:///d:/eclipseWorkspaces/xalanj/xalan-java/tests/"; +    public static final \
String XSL_TRANSFORM_INPUT_DIRPATH_PREFIX = \
"file:///d:/eclipseWorkspaces/xalanj/xalan-java_mukul/tests/";  
-    public static final String XSL_TRANSFORM_GOLD_DIRPATH_PREFIX = \
"d:/eclipseWorkspaces/xalanj/xalan-java/tests/"; +    public static final String \
XSL_TRANSFORM_GOLD_DIRPATH_PREFIX = \
"d:/eclipseWorkspaces/xalanj/xalan-java_mukul/tests/";  
 }
diff --git a/tests/org/apache/xalan/xslt3/XslIterateTests.java \
b/tests/org/apache/xalan/xslt3/XslIterateTests.java index 131a2742..3ef89058 100644
--- a/tests/org/apache/xalan/xslt3/XslIterateTests.java
+++ b/tests/org/apache/xalan/xslt3/XslIterateTests.java
@@ -190,5 +190,15 @@ public class XslIterateTests extends XslTransformTestsUtil {
         
         runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, \
null);  }
+    
+    @Test
+    public void xslIterateTest15() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_c.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test13.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test13.out";             \
 +        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, \
null); +    }
 
 }
diff --git a/tests/xpath_value_comparison/gold/test5.out \
b/tests/xpath_value_comparison/gold/test5.out new file mode 100644
index 00000000..1457921d
--- /dev/null
+++ b/tests/xpath_value_comparison/gold/test5.out
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?><elem>
+  <item pos="2">
+    <a>6.5</a>
+  </item>
+  <item pos="4">
+    <a>-55.23</a>
+  </item>
+  <item pos="6">
+    <b>hello1</b>
+  </item>
+  <item pos="8">
+    <b>5</b>
+  </item>
+</elem>
diff --git a/tests/xpath_value_comparison/gold/test6.out \
b/tests/xpath_value_comparison/gold/test6.out new file mode 100644
index 00000000..360e660c
--- /dev/null
+++ b/tests/xpath_value_comparison/gold/test6.out
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?><elem>
+  <group>
+    <a>1</a>
+    <c>3</c>
+    <e>5</e>
+    <g>7</g>
+  </group>
+  <group>
+    <b>2</b>
+    <d>4</d>
+    <f>6</f>
+    <h>8</h>
+  </group>
+</elem>
diff --git a/tests/xpath_value_comparison/gold/test7.out \
b/tests/xpath_value_comparison/gold/test7.out new file mode 100644
index 00000000..5e55aad3
--- /dev/null
+++ b/tests/xpath_value_comparison/gold/test7.out
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?><elem>
+  <result1>true</result1>
+  <result2>true</result2>
+  <result3>true</result3>
+  <result4>true</result4>
+  <result5>false</result5>
+  <result6>false</result6>
+  <result7>true</result7>
+  <result8>false</result8>
+  <result9>true</result9>
+  <result10>true</result10>
+  <result11>false</result11>
+  <result12>false</result12>
+</elem>
diff --git a/tests/xpath_value_comparison/test1.xsl \
b/tests/xpath_value_comparison/test1.xsl index c10bcc01..b92e074e 100644
--- a/tests/xpath_value_comparison/test1.xsl
+++ b/tests/xpath_value_comparison/test1.xsl
@@ -2,7 +2,10 @@
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                 version="3.0">
                 
-   <!-- Author: mukulg@apache.org -->                
+   <!-- Author: mukulg@apache.org -->
+   
+   <!-- An XSLT stylesheet to test, implementation of XPath 3.1 value 
+        comparison operator 'eq'. -->                
 
    <xsl:output method="xml" indent="yes"/>
 
diff --git a/tests/xpath_value_comparison/test1_b.xml \
b/tests/xpath_value_comparison/test1_b.xml new file mode 100644
index 00000000..24f8e40c
--- /dev/null
+++ b/tests/xpath_value_comparison/test1_b.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<elem>
+   <a>1</a>
+   <b>2</b>
+   <c>3</c>
+   <d>4</d>
+   <e>5</e>
+   <f>6</f>
+   <g>7</g>
+   <h>8</h>
+</elem>
\ No newline at end of file
diff --git a/tests/xpath_value_comparison/test2.xsl \
b/tests/xpath_value_comparison/test2.xsl index 4157a324..9ca96fca 100644
--- a/tests/xpath_value_comparison/test2.xsl
+++ b/tests/xpath_value_comparison/test2.xsl
@@ -4,7 +4,10 @@
                 
    <!-- Author: mukulg@apache.org -->
    
-   <!-- use with test1_a.xml -->                 
+   <!-- use with test1_a.xml -->
+   
+   <!-- An XSLT stylesheet to test, implementation of XPath 3.1 value 
+        comparison operator 'eq'. -->                 
 
    <xsl:output method="xml" indent="yes"/>
 
diff --git a/tests/xpath_value_comparison/test3.xsl \
b/tests/xpath_value_comparison/test3.xsl index 1a79f2d4..28619b38 100644
--- a/tests/xpath_value_comparison/test3.xsl
+++ b/tests/xpath_value_comparison/test3.xsl
@@ -4,7 +4,10 @@
                 
    <!-- Author: mukulg@apache.org -->
    
-   <!-- use with test1_a.xml -->                 
+   <!-- use with test1_a.xml -->
+   
+   <!-- An XSLT stylesheet to test, implementation of XPath 3.1 value 
+        comparison operator 'eq'. -->                 
 
    <xsl:output method="xml" indent="yes"/>
 
diff --git a/tests/xpath_value_comparison/test4.xsl \
b/tests/xpath_value_comparison/test4.xsl index 07de2645..ad9b7c34 100644
--- a/tests/xpath_value_comparison/test4.xsl
+++ b/tests/xpath_value_comparison/test4.xsl
@@ -4,7 +4,10 @@
                 
    <!-- Author: mukulg@apache.org -->
    
-   <!-- use with test1_a.xml -->                 
+   <!-- use with test1_a.xml -->
+   
+   <!-- An XSLT stylesheet to test, implementation of XPath 3.1 value 
+        comparison operator 'ne'. -->                 
 
    <xsl:output method="xml" indent="yes"/>
 
diff --git a/tests/xpath_value_comparison/test3.xsl \
b/tests/xpath_value_comparison/test5.xsl similarity index 75%
copy from tests/xpath_value_comparison/test3.xsl
copy to tests/xpath_value_comparison/test5.xsl
index 1a79f2d4..41088d71 100644
--- a/tests/xpath_value_comparison/test3.xsl
+++ b/tests/xpath_value_comparison/test5.xsl
@@ -4,13 +4,20 @@
                 
    <!-- Author: mukulg@apache.org -->
    
-   <!-- use with test1_a.xml -->                 
+   <!-- use with test1_a.xml -->
+   
+   <!-- An XSLT stylesheet to test, implementation of XPath 3.1 value 
+        comparison operator 'eq'. -->                 
 
    <xsl:output method="xml" indent="yes"/>
 
    <xsl:template match="/elem">
       <elem>
-        <result><xsl:value-of select="a[1] eq a"/></result>
+        <xsl:for-each select="*">
+           <xsl:if test="(position() mod 2) eq 0">
+              <item pos="{position()}"><xsl:copy-of select="."/></item>
+           </xsl:if>
+        </xsl:for-each>
       </elem>
    </xsl:template>
    
diff --git a/tests/xpath_value_comparison/test2.xsl \
b/tests/xpath_value_comparison/test6.xsl similarity index 72%
copy from tests/xpath_value_comparison/test2.xsl
copy to tests/xpath_value_comparison/test6.xsl
index 4157a324..e2bfe7ff 100644
--- a/tests/xpath_value_comparison/test2.xsl
+++ b/tests/xpath_value_comparison/test6.xsl
@@ -4,14 +4,21 @@
                 
    <!-- Author: mukulg@apache.org -->
    
-   <!-- use with test1_a.xml -->                 
+   <!-- use with test1_b.xml -->
+   
+   <!-- An XSLT stylesheet to test, implementation of XPath 3.1 value 
+        comparison operator 'eq'. This stylesheet, also uses an
+        XSLT instruction xsl:for-each-group. -->                 
 
    <xsl:output method="xml" indent="yes"/>
 
    <xsl:template match="/elem">
       <elem>
-        <result1><xsl:value-of select="a[1] eq a[2]"/></result1>
-        <result2><xsl:value-of select="a[1] eq a[3]"/></result2>
+        <xsl:for-each-group select="*" group-by="(. mod 2) eq 0">           
+           <group>
+              <xsl:copy-of select="current-group()"/>
+           </group> 
+        </xsl:for-each-group>
       </elem>
    </xsl:template>
    
diff --git a/tests/xpath_value_comparison/test7.xsl \
b/tests/xpath_value_comparison/test7.xsl new file mode 100644
index 00000000..b1d34e4f
--- /dev/null
+++ b/tests/xpath_value_comparison/test7.xsl
@@ -0,0 +1,63 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                xmlns:xs="http://www.w3.org/2001/XMLSchema"
+                xmlns:java="http://xml.apache.org/xalan/java"
+                exclude-result-prefixes="xs java"
+                version="3.0">
+                
+   <!-- Author: mukulg@apache.org -->
+   
+   <!-- An XSLT stylesheet to test, XPath 3.1 value comparison 
+        operators 'eq' and 'lt'.
+        
+        To be able to test XPath 'eq' operator involving expression
+        like xs:date($currentDateStr) eq current-date(), where the
+        variable $currentDateStr has the current date's string value
+        (with format yyyy-mm-dd) when this test is been run, we use
+        XalanJ's java extension mechanism to get the current date's
+        string value.  
+   -->                
+
+   <xsl:output method="xml" indent="yes"/>
+   
+   <xsl:variable name="currentDateStr" \
select="java:format(java:java.text.SimpleDateFormat.new('yyyy-MM-dd'),  +             \
java:org.apache.xalan.util.XslTransformTestsUtil.getCurrentDate())"/> +               \
 +   <xsl:variable name="timeZoneOffsetStr" \
select="java:org.apache.xalan.util.XslTransformTestsUtil.getDefaultTimezoneOffsetStr()"/> \
 +
+   <xsl:template match="/">            
+      <elem>                       
+        <result1><xsl:value-of select="xs:date('2023-06-19') lt \
current-date()"/></result1> +        <result2><xsl:value-of \
select="xs:date('2023-06-20') lt current-date()"/></result2> +        \
<result3><xsl:value-of select="xs:date('2023-06-21') lt current-date()"/></result3> + \
<result4><xsl:value-of select="xs:date($currentDateStr) eq \
current-date()"/></result4> +        <result5><xsl:value-of \
select="xs:date('2023-06-21Z') eq current-date()"/></result5> +        \
<result6><xsl:value-of select="xs:date('2023-06-15Z') eq \
xs:date('2023-06-15+05:30')"/></result6>         +        <result7><xsl:value-of \
select="xs:date(concat($currentDateStr,$timeZoneOffsetStr)) eq \
current-date()"/></result7> +        <result8><xsl:value-of \
select="xs:date('2023-06-21+10:00') eq xs:date('2023-06-21')"/></result8> +        \
<result9><xsl:value-of select="current-date() eq current-date()"/></result9> +        \
<result10><xsl:value-of select="xs:date('2023-06-21') eq \
xs:date('2023-06-21')"/></result10> +        <result11><xsl:value-of \
select="xs:date('2023-06-19Z') lt xs:date('2023-06-19+05:30')"/></result11> +        \
<result12><xsl:value-of select="xs:date('2023-06-19-06:00') lt \
xs:date('2023-06-19+05:30')"/></result12> +      </elem>
+   </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/xsl_iterate/gold/test13.out b/tests/xsl_iterate/gold/test13.out
new file mode 100644
index 00000000..755e736e
--- /dev/null
+++ b/tests/xsl_iterate/gold/test13.out
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <balance value="12.00" date="2008-09-01"/>
+  <balance value="20.00" date="2008-09-01"/>
+</result>
diff --git a/tests/xsl_iterate/test13.xsl b/tests/xsl_iterate/test13.xsl
new file mode 100644
index 00000000..a70f3157
--- /dev/null
+++ b/tests/xsl_iterate/test13.xsl
@@ -0,0 +1,59 @@
+<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 -->
+   
+  <!-- use with test1_c.xml -->
+   
+  <!-- This XSLT stylesheet, uses xsl:iterate to compute cumulative 
+       totals.
+       
+       This XSLT stylesheet is borrowed from XSLT 3.0 spec, with 
+       slight modifications. -->                 
+  
+  <xsl:output method="xml" indent="yes"/>
+
+  <xsl:template match="/">
+     <result>
+        <xsl:iterate select="transactions/transaction">
+           <xsl:param name="balance" select="0.00"/>
+           <xsl:param name="prevDate"/>
+           <xsl:variable name="newBalance" select="$balance + xs:decimal(@value)"/>
+           <xsl:variable name="thisDate" select="xs:date(@date)"/>
+           <xsl:choose>
+              <xsl:when test="(position() eq 1) or ($thisDate eq $prevDate)">
+                 <balance date="{$thisDate}" value="{format-number($newBalance, \
'0.00')}"/> +                 <xsl:next-iteration>
+                    <xsl:with-param name="balance" select="$newBalance"/>
+                    <xsl:with-param name="prevDate" select="$thisDate"/>
+                 </xsl:next-iteration>
+              </xsl:when>
+              <xsl:otherwise>
+                 <xsl:break/>
+              </xsl:otherwise>
+           </xsl:choose>
+        </xsl:iterate>
+     </result>
+  </xsl:template>
+  
+  <!--
+      * Licensed to the Apache Software Foundation (ASF) under one
+      * or more contributor license agreements. See the NOTICE file
+      * distributed with this work for additional information
+      * regarding copyright ownership. The ASF licenses this file
+      * to you under the Apache License, Version 2.0 (the  "License");
+      * you may not use this file except in compliance with the License.
+      * You may obtain a copy of the License at
+      *
+      *     http://www.apache.org/licenses/LICENSE-2.0
+      *
+      * Unless required by applicable law or agreed to in writing, software
+      * distributed under the License is distributed on an "AS IS" BASIS,
+      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      * See the License for the specific language governing permissions and
+      * limitations under the License.
+  -->
+
+</xsl:stylesheet>


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


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic