[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