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/09/24 15:20:40 UTC

[xalan-java] branch xalan-j_xslt3.0 updated: committing implementation of xpath '+' and '-' operations on xs:date values, and a new related working test case as well. also committing minor code comments improvements on this xalanj dev repos 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 8819d134 committing implementation of xpath '+' and '-' operations on xs:date values, and a new related working test case as well. also committing minor code comments improvements on this xalanj dev repos branch.
     new f614261a Merge pull request #90 from mukulga/xalan-j_xslt3.0_mukul
8819d134 is described below

commit 8819d134eda135fa356b09a907f74af9a3378249
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Sun Sep 24 20:46:39 2023 +0530

    committing implementation of xpath '+' and '-' operations on xs:date values, and a new related working test case as well. also committing minor code comments improvements on this xalanj dev repos branch.
---
 .../xpath/composite/SequenceTypeSupport.java       |   2 +-
 src/org/apache/xpath/operations/Minus.java         |  62 +++++++----
 src/org/apache/xpath/operations/Plus.java          |  62 +++++++----
 src/org/apache/xpath/operations/Variable.java      | 116 +++++++++------------
 src/org/apache/xpath/xs/types/XSDate.java          |  72 ++++++++++++-
 src/org/apache/xpath/xs/types/XSDuration.java      |   2 +-
 .../xalan/xpath3/XsConstructorFunctionTests.java   |  10 ++
 tests/xs_constructor_functions/gold/test13.out     |  15 +++
 tests/xs_constructor_functions/test18.xsl          |  67 ++++++++++++
 tests/xs_constructor_functions/test1_d.xml         |   3 +
 10 files changed, 299 insertions(+), 112 deletions(-)

diff --git a/src/org/apache/xpath/composite/SequenceTypeSupport.java b/src/org/apache/xpath/composite/SequenceTypeSupport.java
index 4b82ab92..bfce0006 100644
--- a/src/org/apache/xpath/composite/SequenceTypeSupport.java
+++ b/src/org/apache/xpath/composite/SequenceTypeSupport.java
@@ -757,7 +757,7 @@ public class SequenceTypeSupport {
                         sequenceTypeNewXPathExprStr = sequenceTypeXPathExprStr;  
                     }
 
-                    String nodeStrVal = node.getNodeValue();
+                    String nodeStrVal = node.getTextContent();
                     XObject xObject = convertXDMValueToAnotherType(new XSString(nodeStrVal), sequenceTypeNewXPathExprStr, 
                                                                                                                       seqExpectedTypeDataInp, xctxt);                       
                     convertedResultSeq.add(xObject); 
diff --git a/src/org/apache/xpath/operations/Minus.java b/src/org/apache/xpath/operations/Minus.java
index febedc9f..898da4d0 100644
--- a/src/org/apache/xpath/operations/Minus.java
+++ b/src/org/apache/xpath/operations/Minus.java
@@ -26,6 +26,7 @@ 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.xs.types.XSDate;
 import org.apache.xpath.xs.types.XSNumericType;
 import org.apache.xpath.xs.types.XSYearMonthDuration;
 
@@ -88,7 +89,7 @@ public class Minus extends Operation
           
           XNodeSet rNodeSet = (XNodeSet)right;
           if (rNodeSet.getLength() > 1) {
-             throw new javax.xml.transform.TransformerException("XPTY0004 : a sequence of more "
+             throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
                                                                                    + "than one item is not allowed as the second "
                                                                                    + "operand of subtraction operator '-'.");  
           }
@@ -104,7 +105,7 @@ public class Minus extends Operation
           
           XNodeSet lNodeSet = (XNodeSet)left;
           if (lNodeSet.getLength() > 1) {
-             throw new javax.xml.transform.TransformerException("XPTY0004 : a sequence of more "
+             throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
                                                                                    + "than one item is not allowed as the first "
                                                                                    + "operand of subtraction operator '-'.");  
           }
@@ -121,7 +122,7 @@ public class Minus extends Operation
           
           XNodeSet rNodeSet = (XNodeSet)right;
           if (rNodeSet.getLength() > 1) {
-             throw new javax.xml.transform.TransformerException("XPTY0004 : a sequence of more "
+             throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
                                                                                    + "than one item is not allowed as the second "
                                                                                    + "operand of subtraction operator '-'.");  
           }
@@ -138,7 +139,7 @@ public class Minus extends Operation
           
           XNodeSet lNodeSet = (XNodeSet)left;
           if (lNodeSet.getLength() > 1) {
-             throw new javax.xml.transform.TransformerException("XPTY0004 : a sequence of more "
+             throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
                                                                                    + "than one item is not allowed as the first "
                                                                                    + "operand of subtraction operator '-'.");  
           }
@@ -155,7 +156,7 @@ public class Minus extends Operation
           
           XNodeSet lNodeSet = (XNodeSet)left;
           if (lNodeSet.getLength() > 1) {
-             throw new javax.xml.transform.TransformerException("XPTY0004 : a sequence of more "
+             throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
                                                                                    + "than one item is not allowed as the first "
                                                                                    + "operand of subtraction operator '-'.");  
           }
@@ -166,7 +167,7 @@ public class Minus extends Operation
           
           XNodeSet rNodeSet = (XNodeSet)right;
           if (rNodeSet.getLength() > 1) {
-             throw new javax.xml.transform.TransformerException("XPTY0004 : a sequence of more "
+             throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
                                                                                    + "than one item is not allowed as the second "
                                                                                    + "operand of subtraction operator '-'.");  
           }
@@ -185,7 +186,7 @@ public class Minus extends Operation
       else if ((left instanceof ResultSequence) && (right instanceof XNumber)) {
           ResultSequence rsLeft = (ResultSequence)left;          
           if (rsLeft.size() > 1) {
-              throw new javax.xml.transform.TransformerException("XPTY0004 : a sequence of more "
+              throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
                                                                                    + "than one item is not allowed as the first "
                                                                                    + "operand of subtraction operator '-'.");  
           }
@@ -201,7 +202,7 @@ public class Minus extends Operation
       else if ((left instanceof XNumber) && (right instanceof ResultSequence)) {
           ResultSequence rsRight = (ResultSequence)right;          
           if (rsRight.size() > 1) {
-              throw new javax.xml.transform.TransformerException("XPTY0004 : a sequence of more "
+              throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
                                                                                    + "than one item is not allowed as the second "
                                                                                    + "operand of subtraction operator '-'.");  
           }
@@ -217,7 +218,7 @@ public class Minus extends Operation
       else if ((left instanceof ResultSequence) && (right instanceof XSNumericType)) {
           ResultSequence rsLeft = (ResultSequence)left;          
           if (rsLeft.size() > 1) {
-              throw new javax.xml.transform.TransformerException("XPTY0004 : a sequence of more "
+              throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
                                                                                    + "than one item is not allowed as the first "
                                                                                    + "operand of subtraction operator '-'.");  
           }
@@ -234,7 +235,7 @@ public class Minus extends Operation
       else if ((left instanceof XSNumericType) && (right instanceof ResultSequence)) {
           ResultSequence rsRight = (ResultSequence)right;          
           if (rsRight.size() > 1) {
-              throw new javax.xml.transform.TransformerException("XPTY0004 : a sequence of more "
+              throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
                                                                                    + "than one item is not allowed as the second "
                                                                                    + "operand of subtraction operator '-'.");  
           }
@@ -251,34 +252,55 @@ public class Minus extends Operation
       else if ((left instanceof ResultSequence) && (right instanceof ResultSequence)) {
           ResultSequence rsLeft = (ResultSequence)left;          
           if (rsLeft.size() > 1) {
-              throw new javax.xml.transform.TransformerException("XPTY0004 : a sequence of more "
+              throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
                                                                                    + "than one item is not allowed as the left "
                                                                                    + "operand of subtraction operator '-'.");  
           }
           
           ResultSequence rsRight = (ResultSequence)right;          
           if (rsRight.size() > 1) {
-              throw new javax.xml.transform.TransformerException("XPTY0004 : a sequence of more "
+              throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
                                                                                    + "than one item is not allowed as the right "
                                                                                    + "operand of subtraction operator '-'.");  
           }
           
-          java.lang.String lStr = XslTransformEvaluationHelper.getStrVal(rsLeft.item(0));
-          double lDouble = (Double.valueOf(lStr)).doubleValue();
+          XObject lArg = ((ResultSequence)left).item(0);
+          XObject rArg = ((ResultSequence)right).item(0);
           
-          java.lang.String rStr = XslTransformEvaluationHelper.getStrVal(rsRight.item(0));
-          double rDouble = (Double.valueOf(rStr)).doubleValue();
+          if (lArg instanceof XSDate) {
+              result = ((XSDate)lArg).subtract(rArg); 
+          }
+          else {
+              java.lang.String lStr = XslTransformEvaluationHelper.getStrVal(lArg);
+              double lDouble = (Double.valueOf(lStr)).doubleValue();
+              
+              java.lang.String rStr = XslTransformEvaluationHelper.getStrVal(rArg);
+              double rDouble = (Double.valueOf(rStr)).doubleValue();
+              
+              result = new XNumber(lDouble - rDouble);
+          }
+      }
+      else if (left instanceof ResultSequence) {
+          ResultSequence rsLeft = (ResultSequence)left;          
+          if (rsLeft.size() > 1) {
+              throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
+                                                                                   + "than one item is not allowed as the left "
+                                                                                   + "operand of subtraction operator '-'.");  
+          }
           
-          result = new XNumber(lDouble - rDouble);
+          XObject lArg = ((ResultSequence)left).item(0);
+          if (lArg instanceof XSDate) {
+              result = ((XSDate)lArg).subtract(right); 
+          }
       }
       else {          
           try {
              result = new XNumber(left.num() - right.num());
           }
           catch (Exception ex) {
-             throw new javax.xml.transform.TransformerException("XPTY0004 : could not apply the "
-                                                                                    + "subtraction operator '-', due to incorrectly "
-                                                                                    + "typed operand(s)."); 
+             throw new javax.xml.transform.TransformerException("XPTY0004 : Could not apply the "
+                                                                                              + "subtraction operator '-', due to incorrectly "
+                                                                                              + "typed operand(s)."); 
           }
       }
       
diff --git a/src/org/apache/xpath/operations/Plus.java b/src/org/apache/xpath/operations/Plus.java
index 0b7b8812..73426a11 100644
--- a/src/org/apache/xpath/operations/Plus.java
+++ b/src/org/apache/xpath/operations/Plus.java
@@ -26,6 +26,7 @@ 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.xs.types.XSDate;
 import org.apache.xpath.xs.types.XSNumericType;
 import org.apache.xpath.xs.types.XSUntyped;
 import org.apache.xpath.xs.types.XSUntypedAtomic;
@@ -125,7 +126,7 @@ public class Plus extends Operation
           
           XNodeSet rNodeSet = (XNodeSet)right;
           if (rNodeSet.getLength() > 1) {
-             throw new javax.xml.transform.TransformerException("XPTY0004 : a sequence of more "
+             throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
                                                                                    + "than one item is not allowed as the second "
                                                                                    + "operand of addition operator '+'.");  
           }
@@ -141,7 +142,7 @@ public class Plus extends Operation
           
           XNodeSet lNodeSet = (XNodeSet)left;
           if (lNodeSet.getLength() > 1) {
-             throw new javax.xml.transform.TransformerException("XPTY0004 : a sequence of more "
+             throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
                                                                                    + "than one item is not allowed as the first "
                                                                                    + "operand of addition operator '+'.");  
           }
@@ -158,7 +159,7 @@ public class Plus extends Operation
           
           XNodeSet rNodeSet = (XNodeSet)right;
           if (rNodeSet.getLength() > 1) {
-             throw new javax.xml.transform.TransformerException("XPTY0004 : a sequence of more "
+             throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
                                                                                    + "than one item is not allowed as the second "
                                                                                    + "operand of addition operator '+'.");  
           }
@@ -175,7 +176,7 @@ public class Plus extends Operation
           
           XNodeSet lNodeSet = (XNodeSet)left;
           if (lNodeSet.getLength() > 1) {
-             throw new javax.xml.transform.TransformerException("XPTY0004 : a sequence of more "
+             throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
                                                                                    + "than one item is not allowed as the first "
                                                                                    + "operand of addition operator '+'.");  
           }
@@ -192,7 +193,7 @@ public class Plus extends Operation
           
           XNodeSet lNodeSet = (XNodeSet)left;
           if (lNodeSet.getLength() > 1) {
-             throw new javax.xml.transform.TransformerException("XPTY0004 : a sequence of more "
+             throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
                                                                                    + "than one item is not allowed as the first "
                                                                                    + "operand of addition operator '+'.");  
           }
@@ -203,7 +204,7 @@ public class Plus extends Operation
           
           XNodeSet rNodeSet = (XNodeSet)right;
           if (rNodeSet.getLength() > 1) {
-             throw new javax.xml.transform.TransformerException("XPTY0004 : a sequence of more "
+             throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
                                                                                    + "than one item is not allowed as the second "
                                                                                    + "operand of addition operator '+'.");  
           }
@@ -220,7 +221,7 @@ public class Plus extends Operation
       else if ((left instanceof ResultSequence) && (right instanceof XNumber)) {
           ResultSequence rsLeft = (ResultSequence)left;          
           if (rsLeft.size() > 1) {
-              throw new javax.xml.transform.TransformerException("XPTY0004 : a sequence of more "
+              throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
                                                                                    + "than one item is not allowed as the first "
                                                                                    + "operand of addition operator '+'.");  
           }
@@ -235,7 +236,7 @@ public class Plus extends Operation
       else if ((left instanceof XNumber) && (right instanceof ResultSequence)) {
           ResultSequence rsRight = (ResultSequence)right;          
           if (rsRight.size() > 1) {
-              throw new javax.xml.transform.TransformerException("XPTY0004 : a sequence of more "
+              throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
                                                                                    + "than one item is not allowed as the second "
                                                                                    + "operand of addition operator '+'.");  
           }
@@ -250,7 +251,7 @@ public class Plus extends Operation
       else if ((left instanceof ResultSequence) && (right instanceof XSNumericType)) {
           ResultSequence rsLeft = (ResultSequence)left;          
           if (rsLeft.size() > 1) {
-              throw new javax.xml.transform.TransformerException("XPTY0004 : a sequence of more "
+              throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
                                                                                    + "than one item is not allowed as the first "
                                                                                    + "operand of addition operator '+'.");  
           }
@@ -267,7 +268,7 @@ public class Plus extends Operation
       else if ((left instanceof XSNumericType) && (right instanceof ResultSequence)) {
           ResultSequence rsRight = (ResultSequence)right;          
           if (rsRight.size() > 1) {
-              throw new javax.xml.transform.TransformerException("XPTY0004 : a sequence of more "
+              throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
                                                                                    + "than one item is not allowed as the second "
                                                                                    + "operand of addition operator '+'.");  
           }
@@ -284,34 +285,55 @@ public class Plus extends Operation
       else if ((left instanceof ResultSequence) && (right instanceof ResultSequence)) {
           ResultSequence rsLeft = (ResultSequence)left;          
           if (rsLeft.size() > 1) {
-              throw new javax.xml.transform.TransformerException("XPTY0004 : a sequence of more "
+              throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
                                                                                    + "than one item is not allowed as the left "
                                                                                    + "operand of addition operator '+'.");  
           }
           
           ResultSequence rsRight = (ResultSequence)right;          
           if (rsRight.size() > 1) {
-              throw new javax.xml.transform.TransformerException("XPTY0004 : a sequence of more "
+              throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
                                                                                    + "than one item is not allowed as the right "
                                                                                    + "operand of addition operator '+'.");  
           }
           
-          java.lang.String lStr = XslTransformEvaluationHelper.getStrVal(rsLeft.item(0));
-          double lDouble = (Double.valueOf(lStr)).doubleValue();
+          XObject lArg = ((ResultSequence)left).item(0);
+          XObject rArg = ((ResultSequence)right).item(0);
           
-          java.lang.String rStr = XslTransformEvaluationHelper.getStrVal(rsRight.item(0));
-          double rDouble = (Double.valueOf(rStr)).doubleValue();
+          if (lArg instanceof XSDate) {
+             result = ((XSDate)lArg).add(rArg); 
+          }
+          else {
+             java.lang.String lStr = XslTransformEvaluationHelper.getStrVal(rsLeft.item(0));
+             double lDouble = (Double.valueOf(lStr)).doubleValue();
+              
+             java.lang.String rStr = XslTransformEvaluationHelper.getStrVal(rsRight.item(0));
+             double rDouble = (Double.valueOf(rStr)).doubleValue();
+              
+             result = new XNumber(lDouble + rDouble);
+          }
+      }
+      else if (left instanceof ResultSequence) {
+          ResultSequence rsLeft = (ResultSequence)left;          
+          if (rsLeft.size() > 1) {
+              throw new javax.xml.transform.TransformerException("XPTY0004 : A sequence of more "
+                                                                                   + "than one item is not allowed as the left "
+                                                                                   + "operand of addition operator '+'.");  
+          }
           
-          result = new XNumber(lDouble + rDouble);
+          XObject lArg = ((ResultSequence)left).item(0);
+          if (lArg instanceof XSDate) {
+              result = ((XSDate)lArg).add(right); 
+          }
       }
       else {
           try {
              result = new XNumber(left.num() + right.num());
           }
           catch (Exception ex) {
-             throw new javax.xml.transform.TransformerException("XPTY0004 : could not apply the "
-                                                                                     + "addition operator '+', due to incorrectly "
-                                                                                     + "typed operand(s)."); 
+             throw new javax.xml.transform.TransformerException("XPTY0004 : Could not apply the "
+                                                                                              + "addition operator '+', due to incorrectly "
+                                                                                              + "typed operand(s)."); 
           }
       }
       
diff --git a/src/org/apache/xpath/operations/Variable.java b/src/org/apache/xpath/operations/Variable.java
index 8ca1185d..046c9a6a 100644
--- a/src/org/apache/xpath/operations/Variable.java
+++ b/src/org/apache/xpath/operations/Variable.java
@@ -37,7 +37,6 @@ import org.apache.xpath.objects.XNodeSet;
 import org.apache.xpath.objects.XObject;
 import org.apache.xpath.res.XPATHErrorResources;
 
-
 /**
  * The variable reference expression executer.
  */
@@ -99,10 +98,6 @@ public class Variable extends Expression implements PathComponent
   {
   	return m_isGlobal;
   }
-
-  
-  
-
   
   protected boolean m_isGlobal = false;
   
@@ -198,11 +193,10 @@ public class Variable extends Expression implements PathComponent
 
 
   /**
-   * Dereference the variable, and return the reference value.  Note that lazy 
-   * evaluation will occur.  If a variable within scope is not found, a warning 
+   * Dereference the variable, and return the reference value. Note that lazy 
+   * evaluation will occur. If a variable within scope is not found, a warning 
    * will be sent to the error listener, and an empty nodeset will be returned.
    *
-   *
    * @param xctxt The runtime execution context.
    *
    * @return The evaluated variable, or an empty nodeset if not found.
@@ -211,69 +205,55 @@ public class Variable extends Expression implements PathComponent
    */
   public XObject execute(XPathContext xctxt, boolean destructiveOK) throws javax.xml.transform.TransformerException
   {
-    org.apache.xml.utils.PrefixResolver xprefixResolver = xctxt.getNamespaceContext();
-
-    XObject result;
-    
-    Map<QName, XObject> xpathVarMap = xctxt.getXPathVarMap();
-    XObject varValue = xpathVarMap.get(m_qname);
-    
-    if (varValue != null) {
-        // dereference, XPath 3.1 variable reference
-        if (varValue instanceof XNodeSet) {
-           result = ((XNodeSet)varValue).getFresh();    
-        }
-        else {
-           result = varValue;
+      
+        XObject result = null;
+        
+        Map<QName, XObject> xpathVarMap = xctxt.getXPathVarMap();
+        XObject varValue = xpathVarMap.get(m_qname);
+        
+        if (varValue != null) {
+           // added for XPath 3.1
+           if (varValue instanceof XNodeSet) {
+              result = ((XNodeSet)varValue).getFresh();    
+           }
+           else {
+              result = varValue;
+           }
+            
+           return result;
         }
         
+        try {
+           if (m_fixUpWasCalled) {    
+              if (m_isGlobal) {
+                 result = xctxt.getVarStack().getGlobalVariable(xctxt, m_index, destructiveOK);
+              }
+              else {
+                 result = xctxt.getVarStack().getLocalVariable(xctxt, m_index, destructiveOK);
+              }
+           } 
+           else {  
+              result = xctxt.getVarStack().getVariableOrParam(xctxt,m_qname);
+           }
+        }
+        catch (javax.xml.transform.TransformerException ex) {
+           if (m_qname == null) {
+              throw ex;   
+           }
+           else {
+              throw new javax.xml.transform.TransformerException("Variable $" + m_qname.toString() + " "
+                                                                                               + "accessed before it is bound!."); 
+           }
+        }
+      
+        if (result == null) {
+           // This should now never happen...
+           warn(xctxt, XPATHErrorResources.WG_ILLEGAL_VARIABLE_REFERENCE, 
+                                                                       new Object[]{ m_qname.getLocalPart() });            
+           result = new XNodeSet(xctxt.getDTMManager());
+        }
+      
         return result;
-    }
-    
-    // Is the variable fetched always the same?
-    // XObject result = xctxt.getVariable(m_qname);
-    if(m_fixUpWasCalled)
-    {    
-      if(m_isGlobal)
-        result = xctxt.getVarStack().getGlobalVariable(xctxt, m_index, destructiveOK);
-      else
-        result = xctxt.getVarStack().getLocalVariable(xctxt, m_index, destructiveOK);
-    } 
-    else {  
-    	result = xctxt.getVarStack().getVariableOrParam(xctxt,m_qname);
-    }
-  
-      if (null == result)
-      {
-        // This should now never happen...
-        warn(xctxt, XPATHErrorResources.WG_ILLEGAL_VARIABLE_REFERENCE,
-             new Object[]{ m_qname.getLocalPart() });  //"VariableReference given for variable out "+
-  //      (new RuntimeException()).printStackTrace();
-  //      error(xctxt, XPATHErrorResources.ER_COULDNOT_GET_VAR_NAMED,
-  //            new Object[]{ m_qname.getLocalPart() });  //"Could not get variable named "+varName);
-        
-        result = new XNodeSet(xctxt.getDTMManager());
-      }
-  
-      return result;
-//    }
-//    else
-//    {
-//      // Hack city... big time.  This is needed to evaluate xpaths from extensions, 
-//      // pending some bright light going off in my head.  Some sort of callback?
-//      synchronized(this)
-//      {
-//      	org.apache.xalan.templates.ElemVariable vvar= getElemVariable();
-//      	if(null != vvar)
-//      	{
-//          m_index = vvar.getIndex();
-//          m_isGlobal = vvar.getIsTopLevel();
-//          m_fixUpWasCalled = true;
-//          return execute(xctxt);
-//      	}
-//      }
-//      throw new javax.xml.transform.TransformerException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_VAR_NOT_RESOLVABLE, new Object[]{m_qname.toString()})); //"Variable not resolvable: "+m_qname);
-//    }
   }
   
   /**
diff --git a/src/org/apache/xpath/xs/types/XSDate.java b/src/org/apache/xpath/xs/types/XSDate.java
index 798d5ac9..e4a88b7d 100644
--- a/src/org/apache/xpath/xs/types/XSDate.java
+++ b/src/org/apache/xpath/xs/types/XSDate.java
@@ -23,6 +23,7 @@ import java.util.GregorianCalendar;
 import javax.xml.transform.TransformerException;
 
 import org.apache.xpath.objects.ResultSequence;
+import org.apache.xpath.objects.XObject;
 
 /**
  * An XML Schema data type representation, of the xs:date datatype.
@@ -43,8 +44,8 @@ public class XSDate extends XSCalendarType {
     
     private XSDuration _tz;
     
-    // stores the fact that, whether this XSDate object is constructed
-    // via XPath function call fn:current-date().
+    // The value of this class field, stores the fact that whether this XSDate
+    // object is constructed via XPath function call fn:current-date().
     private boolean isPopulatedFromFnCurrentDate = false;
     
     /**
@@ -308,6 +309,73 @@ public class XSDate extends XSCalendarType {
         
         return isDateAfter; 
     }
+    
+    /**
+    * Implementation of subtraction operation between this XSDate value, and a supplied value
+    * (as per XPath 3.1 spec, xs:date, xs:yearMonthDuration and xs:dayTimeDuration are the only
+    * permissible data type values, that may be subtracted from an xs:date value).
+    */
+    public XObject subtract(XObject xObject) throws TransformerException {
+        XObject result = null;
+        
+        if (!((xObject instanceof XSDate) || (xObject instanceof XSYearMonthDuration)
+                                          || (xObject instanceof XSDayTimeDuration))) {
+           throw new TransformerException("XPTY0004 : The values of types xs:date, xs:yearMonthDuration or "
+                                                                                 + "xs:dayTimeDuration are only ones that may be subtracted from an xs:date value.");
+        }
+        
+        if (xObject instanceof XSDate) {
+           Calendar cal1 = getCalendar();
+           Calendar cal2 = ((XSDate)xObject).getCalendar();
+           long diffDurationMilliSecs = cal1.getTimeInMillis() - cal2.getTimeInMillis();
+           result = new XSDuration(diffDurationMilliSecs / 1000);
+        }
+        else if (xObject instanceof XSYearMonthDuration) {
+           XSYearMonthDuration argVal = (XSYearMonthDuration)xObject;
+           Calendar cal1 = (Calendar)((getCalendar()).clone());
+           cal1.add(Calendar.MONTH, argVal.monthValue() * -1);
+           result = new XSDate(cal1, getTimezone());
+        }
+        else if (xObject instanceof XSDayTimeDuration) {
+           XSDayTimeDuration argVal = (XSDayTimeDuration)xObject;
+           double argValSecs = argVal.value();
+           Calendar cal1 = (Calendar)((getCalendar()).clone());
+           cal1.setTimeInMillis(cal1.getTimeInMillis() + ((((long)argValSecs * 1000)) * -1));
+           result = new XSDate(cal1, getTimezone());
+        }
+        
+        return result;
+    }
+    
+    /**
+    * Implementation of addition operation between this XSDate value, and a supplied value
+    * (as per XPath 3.1 spec, xs:yearMonthDuration and xs:dayTimeDuration are the only permissible 
+    * data type values, that may be added to an xs:date value).
+    */
+    public XObject add(XObject xObject) throws TransformerException {
+        XObject result = null;
+        
+        if (!((xObject instanceof XSYearMonthDuration) || (xObject instanceof XSDayTimeDuration))) {
+           throw new TransformerException("XPTY0004 : The values of types xs:yearMonthDuration or "
+                                                                               + "xs:dayTimeDuration are only ones that may be added to an xs:date value.");
+        }
+        
+        if (xObject instanceof XSYearMonthDuration) {
+           XSYearMonthDuration argVal = (XSYearMonthDuration)xObject;
+           Calendar cal1 = (Calendar)((getCalendar()).clone());
+           cal1.add(Calendar.MONTH, argVal.monthValue());
+           result = new XSDate(cal1, getTimezone());
+        }
+        else if (xObject instanceof XSDayTimeDuration) {
+           XSDayTimeDuration argVal = (XSDayTimeDuration)xObject;
+           double argValSecs = argVal.value();
+           Calendar cal1 = (Calendar)((getCalendar()).clone());
+           cal1.setTimeInMillis(cal1.getTimeInMillis() + ((((long)argValSecs * 1000))));
+           result = new XSDate(cal1, getTimezone());
+        }
+        
+        return result;
+    }
 
     public boolean isPopulatedFromFnCurrentDate() {
         return isPopulatedFromFnCurrentDate;
diff --git a/src/org/apache/xpath/xs/types/XSDuration.java b/src/org/apache/xpath/xs/types/XSDuration.java
index 385e7212..7761d1ca 100644
--- a/src/org/apache/xpath/xs/types/XSDuration.java
+++ b/src/org/apache/xpath/xs/types/XSDuration.java
@@ -458,7 +458,7 @@ public class XSDuration extends XSCtrType {
     }
     
     public int getType() {
-        return CLASS_XS_DURATION;
+       return CLASS_XS_DURATION;
     }
     
     /**
diff --git a/tests/org/apache/xalan/xpath3/XsConstructorFunctionTests.java b/tests/org/apache/xalan/xpath3/XsConstructorFunctionTests.java
index 6da5c203..a7a29afb 100644
--- a/tests/org/apache/xalan/xpath3/XsConstructorFunctionTests.java
+++ b/tests/org/apache/xalan/xpath3/XsConstructorFunctionTests.java
@@ -217,5 +217,15 @@ public class XsConstructorFunctionTests extends XslTransformTestsUtil {
         
         runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
     }
+    
+    @Test
+    public void XsConstructorFunctionsTest18() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_d.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test18.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test13.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
 
 }
diff --git a/tests/xs_constructor_functions/gold/test13.out b/tests/xs_constructor_functions/gold/test13.out
new file mode 100644
index 00000000..5cfa5faf
--- /dev/null
+++ b/tests/xs_constructor_functions/gold/test13.out
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>2007-10-05</one>
+  <two>2003-10-03</two>
+  <three>P5D</three>
+  <snip/>
+  <plus value="2007-10-10"/>
+  <plus value="2007-10-10"/>
+  <plus value="2007-10-08"/>
+  <plus value="2013-05-05"/>
+  <snip/>
+  <diff value="P1463D"/>
+  <diff value="2007-10-04"/>
+  <diff value="2007-10-02"/>
+  <diff value="2005-07-05"/>
+</result>
diff --git a/tests/xs_constructor_functions/test18.xsl b/tests/xs_constructor_functions/test18.xsl
new file mode 100644
index 00000000..b1574560
--- /dev/null
+++ b/tests/xs_constructor_functions/test18.xsl
@@ -0,0 +1,67 @@
+<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_d.xml -->
+  
+  <!-- An XSLT stylesheet test case, to test XPath '+' and
+       '-' operations on xs:date values.
+  -->                
+                
+  <xsl:output method="xml" indent="yes"/>
+
+  <xsl:template match="/info">
+     <result>        
+        <xsl:variable name="var1" as="xs:date">
+     	   <xsl:sequence select="str"/>
+        </xsl:variable>
+        <xsl:variable name="var2" as="xs:date">
+           <xsl:sequence select="xs:date('2003-10-03')"/>
+        </xsl:variable>
+        <xsl:variable name="var3" as="xs:dayTimeDuration">
+           <xsl:sequence select="xs:dayTimeDuration('P5D')"/>
+        </xsl:variable>
+        <one>
+           <xsl:value-of select="$var1"/>
+        </one>
+        <two>
+           <xsl:value-of select="$var2"/>
+        </two>
+        <three>
+           <xsl:value-of select="$var3"/>
+        </three>
+        <snip/>
+        <plus value="{$var1 + $var3}"/>
+        <plus value="{$var1 + xs:dayTimeDuration('P5D')}"/>
+        <plus value="{$var1 + xs:dayTimeDuration('PT72H')}"/>
+        <plus value="{$var1 + xs:yearMonthDuration('P5Y7M')}"/>
+        <snip/>
+        <diff value="{$var1 - $var2}"/>        
+        <diff value="{$var1 - xs:dayTimeDuration('P1D')}"/>
+        <diff value="{$var1 - xs:dayTimeDuration('PT72H')}"/>
+        <diff value="{$var1 - xs:yearMonthDuration('P2Y3M')}"/>        
+     </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/xs_constructor_functions/test1_d.xml b/tests/xs_constructor_functions/test1_d.xml
new file mode 100644
index 00000000..610c0730
--- /dev/null
+++ b/tests/xs_constructor_functions/test1_d.xml
@@ -0,0 +1,3 @@
+<info>
+   <str>2007-10-05</str>
+</info>
\ No newline at end of file


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