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 2026/05/16 05:10:25 UTC
(xalan-java) branch xalan-j_xslt3.0_mvn updated: committing xalan-j xslt 3.0 implementation improvements
This is an automated email from the ASF dual-hosted git repository.
mukulgandhi pushed a commit to branch xalan-j_xslt3.0_mvn
in repository https://gitbox.apache.org/repos/asf/xalan-java.git
The following commit(s) were added to refs/heads/xalan-j_xslt3.0_mvn by this push:
new cc74861e9 committing xalan-j xslt 3.0 implementation improvements
cc74861e9 is described below
commit cc74861e90ae1e0661f4aba5299f78349a37d123
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Sat May 16 10:39:50 2026 +0530
committing xalan-j xslt 3.0 implementation improvements
---
README | 8 +-
src/main/java/org/apache/xalan/xslt/Process.java | 22 ++--
src/main/java/org/apache/xml/utils/Constants.java | 13 ++-
.../java/org/apache/xpath/objects/XObject.java | 20 ++++
.../java/org/apache/xpath/operations/CastAs.java | 17 ++-
src/main/java/org/apache/xpath/operations/Div.java | 48 +++++++-
.../java/org/apache/xpath/operations/IDiv.java | 40 ++++++-
.../org/apache/xpath/operations/InstanceOf.java | 54 +++++++--
.../java/org/apache/xpath/operations/Minus.java | 61 ++++++++++-
src/main/java/org/apache/xpath/operations/Mod.java | 40 ++++++-
.../java/org/apache/xpath/operations/Mult.java | 117 +++++++++++++++++---
.../java/org/apache/xpath/operations/Plus.java | 72 ++++++++++--
.../xalan/tests/main/XalanXsl3TestSuite2.java | 3 +-
.../xalan/tests/util/XslTransformTestsUtil.java | 4 +-
.../xalan/tests/xpath3/XslSchemaAwareTests.java | 122 +++++++++++++++++++++
src/test/resources/xsl_schema_aware/test1.xml | 6 +
src/test/resources/xsl_schema_aware/test1.xsd | 14 +++
src/test/resources/xsl_schema_aware/test1.xsl | 42 +++++++
18 files changed, 628 insertions(+), 75 deletions(-)
diff --git a/README b/README
index 4520f636b..4a18d4d03 100644
--- a/README
+++ b/README
@@ -17,7 +17,7 @@
Copyright 1999-2026 The Apache Software Foundation
-Document last modified : 2026-05-08
+Document last modified : 2026-05-16
Authors:
Gary Gregory <gg...@apache.org>
@@ -99,16 +99,16 @@ When this Maven build command is run, results like following shall be produced:
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running org.apache.xalan.tests.main.XalanXsl3TestSuite2
-[INFO] Tests run: 664, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 18.257 s - in org.apache.xalan.tests.main.XalanXsl3TestSuite2
+[INFO] Tests run: 665, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 15.216 s - in org.apache.xalan.tests.main.XalanXsl3TestSuite2
[INFO]
[INFO] Results:
[INFO]
-[INFO] Tests run: 664, Failures: 0, Errors: 0, Skipped: 0
+[INFO] Tests run: 665, Failures: 0, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
-[INFO] Total time: 54.143 s
+[INFO] Total time: 45.232 s
After verifying that, Xalan Java XSLT 3.0 src code passes all the applicable XSL test cases, user may install Xalan Java
diff --git a/src/main/java/org/apache/xalan/xslt/Process.java b/src/main/java/org/apache/xalan/xslt/Process.java
index 0ad79b2ab..eb79d2a86 100644
--- a/src/main/java/org/apache/xalan/xslt/Process.java
+++ b/src/main/java/org/apache/xalan/xslt/Process.java
@@ -961,26 +961,26 @@ public class Process
inpSrc.setEncoding(encoding);
}
- Node xmlDoc = null;
+ Node node = null;
if (isSchemaValidation) {
DOMParser parser = new DOMParser();
- parser.setFeature("http://xml.org/sax/features/validation", true);
- parser.setFeature("http://apache.org/xml/features/validation/schema", true);
- parser.setFeature("http://apache.org/xml/features/validation/schema-full-checking", true);
-
- parser.setProperty("http://apache.org/xml/properties/dom/document-class-name",
- "org.apache.xerces.dom.PSVIDocumentImpl");
+ parser.setFeature(Constants.XML_VALIDATION_FEATURE, true);
+ parser.setFeature(Constants.XML_SCHEMA_VALIDATION_FEATURE, true);
+ parser.setFeature(Constants.XML_SCHEMA_FULL_CHECKING_FEATURE, true);
+
+ parser.setProperty(Constants.XML_DOM_DOCUMENT_CLASS_NAME, Constants.XERCES_PSVI_DOCUMENT_IMPL);
+
parser.parse(inpSrc);
- xmlDoc = parser.getDocument();
+ node = parser.getDocument();
}
else {
- xmlDoc = docBuilder.parse(inpSrc);
+ node = docBuilder.parse(inpSrc);
}
Document doc = docBuilder.newDocument();
org.w3c.dom.DocumentFragment outNode = doc.createDocumentFragment();
- transformer.transform(new DOMSource(xmlDoc, inFileName), new DOMResult(outNode));
+ transformer.transform(new DOMSource(node, inFileName), new DOMResult(outNode));
// Now serialize output to disk with identity transformer
Transformer identityTransformer = stf.newTransformer();
@@ -1017,7 +1017,7 @@ public class Process
// Using an XMLReader to construct SAXSource for an XML input
// document, enables correct XML namespace processing.
- XMLReader xmlReader = XMLReaderFactory.createXMLReader();
+ XMLReader xmlReader = XMLReaderFactory.createXMLReader();
transformer.transform(new SAXSource(xmlReader, inpSrc), new DOMResult(outNode));
diff --git a/src/main/java/org/apache/xml/utils/Constants.java b/src/main/java/org/apache/xml/utils/Constants.java
index 300568559..b4acd59f1 100644
--- a/src/main/java/org/apache/xml/utils/Constants.java
+++ b/src/main/java/org/apache/xml/utils/Constants.java
@@ -15,9 +15,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/*
- * $Id$
- */
package org.apache.xml.utils;
/**
@@ -111,6 +108,16 @@ public class Constants
*/
public static final double XSLTVERSUPPORTED = 1.0;
+ public static final String XML_VALIDATION_FEATURE = "http://xml.org/sax/features/validation";
+
+ public static final String XML_SCHEMA_VALIDATION_FEATURE = "http://apache.org/xml/features/validation/schema";
+
+ public static final String XML_SCHEMA_FULL_CHECKING_FEATURE = "http://apache.org/xml/features/validation/schema-full-checking";
+
+ public static final String XML_DOM_DOCUMENT_CLASS_NAME = "http://apache.org/xml/properties/dom/document-class-name";
+
+ public static final String XERCES_PSVI_DOCUMENT_IMPL = "org.apache.xerces.dom.PSVIDocumentImpl";
+
/**
* Xalan's XSLT 3.0 JAXP factory object information.
*/
diff --git a/src/main/java/org/apache/xpath/objects/XObject.java b/src/main/java/org/apache/xpath/objects/XObject.java
index 5c361aec6..ccf6b74fd 100644
--- a/src/main/java/org/apache/xpath/objects/XObject.java
+++ b/src/main/java/org/apache/xpath/objects/XObject.java
@@ -41,6 +41,7 @@ import org.apache.xpath.XPathContext;
import org.apache.xpath.XPathException;
import org.apache.xpath.XPathVisitor;
import org.apache.xpath.compiler.Keywords;
+import org.apache.xpath.composite.SequenceTypeData;
import org.apache.xpath.functions.XSL3FunctionService;
import org.apache.xpath.res.XPATHErrorResources;
import org.apache.xpath.types.DateTimeUtil;
@@ -128,6 +129,17 @@ public class XObject extends Expression implements Serializable, Cloneable
* and for clauses.
*/
private boolean m_homogeneous_source = false;
+
+ /**
+ * An XPath 3.1 sequence type information, telling the
+ * type of this XPath object (when not equals to null), if
+ * this object instance is a result of XPath 3.1 "cast as"
+ * expression.
+ *
+ * This helps to, correctly infer the type of this XPath object
+ * within XPath 3.1 expressions like "instance of".
+ */
+ private SequenceTypeData m_cast_as_type = null;
/**
* Create an XObject.
@@ -2444,5 +2456,13 @@ public class XObject extends Expression implements Serializable, Cloneable
public void setHomogeneousSource(boolean homogeneousSource) {
this.m_homogeneous_source = homogeneousSource;
}
+
+ public SequenceTypeData getCastAsType() {
+ return m_cast_as_type;
+ }
+
+ public void setCastAsType(SequenceTypeData seqTypedData) {
+ this.m_cast_as_type = seqTypedData;
+ }
}
diff --git a/src/main/java/org/apache/xpath/operations/CastAs.java b/src/main/java/org/apache/xpath/operations/CastAs.java
index 25f354e0f..6944bfef5 100644
--- a/src/main/java/org/apache/xpath/operations/CastAs.java
+++ b/src/main/java/org/apache/xpath/operations/CastAs.java
@@ -15,9 +15,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/*
- * $Id$
- */
package org.apache.xpath.operations;
import org.apache.xalan.templates.ElemTemplateElement;
@@ -49,10 +46,10 @@ public class CastAs extends Operation
/**
* 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.
+ * @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.
+ * @return non-null reference to the XObject that represents the result of the operation
*
* @throws javax.xml.transform.TransformerException
*/
@@ -109,14 +106,16 @@ public class CastAs extends Operation
}
}
finally {
- // Reset the value of variable XslTransformSharedDatastore.xpathCallingOpCode
+ // Reset the value of variable XslTransformData.m_xpathCallingOpCode
XslTransformData.m_xpathCallingOpCode = Integer.MIN_VALUE;
}
- // Evaluate XPath "cast as" expression, when XPath "idiv" expression
- // evaluation was not requested within original XPath input expression.
+ // Evaluate an XPath 3.1 "cast as" expression, when XPath "idiv" expression
+ // evaluation has not been requested within original XPath expression input.
result = SequenceTypeSupport.castXdmValueToAnotherType(left, null, seqTypedData, xpathContext);
+ result.setCastAsType(seqTypedData);
+
return result;
}
diff --git a/src/main/java/org/apache/xpath/operations/Div.java b/src/main/java/org/apache/xpath/operations/Div.java
index 0f2ee0a05..cb021ce1a 100644
--- a/src/main/java/org/apache/xpath/operations/Div.java
+++ b/src/main/java/org/apache/xpath/operations/Div.java
@@ -48,12 +48,14 @@ import org.apache.xpath.objects.XNumber;
import org.apache.xpath.objects.XObject;
import org.apache.xpath.objects.XPathInlineFunction;
import org.apache.xpath.objects.XPathMap;
+import org.apache.xpath.objects.XString;
import org.w3c.dom.Node;
import xml.xpath31.processor.types.XSDayTimeDuration;
import xml.xpath31.processor.types.XSDecimal;
import xml.xpath31.processor.types.XSDouble;
import xml.xpath31.processor.types.XSNumericType;
+import xml.xpath31.processor.types.XSString;
import xml.xpath31.processor.types.XSUntyped;
import xml.xpath31.processor.types.XSUntypedAtomic;
import xml.xpath31.processor.types.XSYearMonthDuration;
@@ -279,20 +281,54 @@ public class Div extends XPathArithmeticOp
}
}
- // Validating an XPath 3.1 operator 'div', operands compatibility for addition
- // Ref : XPath 3.1 operator mapping, https://www.w3.org/TR/xpath-31/#mapping
- if ((XMLConstants.W3C_XML_SCHEMA_NS_URI).equals(typeNs1) && (XMLConstants.W3C_XML_SCHEMA_NS_URI).equals(typeNs2)) {
+ if (left instanceof XSNumericType) {
+ if ((right instanceof XSString) || (right instanceof XString)) {
+ java.lang.String str2 = XslTransformEvaluationHelper.getStrVal(right);
+
+ try {
+ double dbl2 = Double.valueOf(str2);
+ right = new XSDouble(dbl2);
+
+ typeName2 = "double";
+ typeNs2 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
+ }
+ catch (NumberFormatException ex) {
+ // no op
+ }
+ }
+ }
+
+ if (right instanceof XSNumericType) {
+ if ((left instanceof XSString) || (left instanceof XString)) {
+ java.lang.String str1 = XslTransformEvaluationHelper.getStrVal(left);
+
+ try {
+ double dbl1 = Double.valueOf(str1);
+ left = new XSDouble(dbl1);
+
+ typeName1 = "double";
+ typeNs1 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
+ }
+ catch (NumberFormatException ex) {
+ // no op
+ }
+ }
+ }
+
+ // Validating an XPath 3.1 operator 'div', operands compatibility for division
+ // Ref : XPath 3.1 operator mapping, https://www.w3.org/TR/xpath-31/#mapping
+ if ((XMLConstants.W3C_XML_SCHEMA_NS_URI).equals(typeNs1) && (XMLConstants.W3C_XML_SCHEMA_NS_URI).equals(typeNs2)) {
if ((isXsBuiltInTypeNumeric(typeName1) && !isXsBuiltInTypeNumeric(typeName2)) ||
(isXsBuiltInTypeNumeric(typeName2) && !isXsBuiltInTypeNumeric(typeName1))) {
- throw new javax.xml.transform.TransformerException("FOTY0013 : An XPath 3.1 operator 'div' cannot add values of schema "
+ throw new javax.xml.transform.TransformerException("FOTY0013 : An XPath 3.1 operator 'div' cannot apply values of schema "
+ "types " + typeName1 + " and " + typeName2 + ".");
}
else if ("yearMonthDuration".equals(typeName1) && !(isXsBuiltInTypeNumeric(typeName2) || "yearMonthDuration".equals(typeName2))) {
- throw new javax.xml.transform.TransformerException("FOTY0013 : An XPath 3.1 operator 'div' cannot add values of schema "
+ throw new javax.xml.transform.TransformerException("FOTY0013 : An XPath 3.1 operator 'div' cannot apply values of schema "
+ "types " + typeName1 + " and " + typeName2 + ".");
}
else if ("dayTimeDuration".equals(typeName1) && !(isXsBuiltInTypeNumeric(typeName2) || "dayTimeDuration".equals(typeName2))) {
- throw new javax.xml.transform.TransformerException("FOTY0013 : An XPath 3.1 operator 'div' cannot add values of schema "
+ throw new javax.xml.transform.TransformerException("FOTY0013 : An XPath 3.1 operator 'div' cannot apply values of schema "
+ "types " + typeName1 + " and " + typeName2 + ".");
}
diff --git a/src/main/java/org/apache/xpath/operations/IDiv.java b/src/main/java/org/apache/xpath/operations/IDiv.java
index df0666826..852da398d 100644
--- a/src/main/java/org/apache/xpath/operations/IDiv.java
+++ b/src/main/java/org/apache/xpath/operations/IDiv.java
@@ -49,12 +49,14 @@ import org.apache.xpath.objects.XNumber;
import org.apache.xpath.objects.XObject;
import org.apache.xpath.objects.XPathInlineFunction;
import org.apache.xpath.objects.XPathMap;
+import org.apache.xpath.objects.XString;
import org.w3c.dom.Node;
import xml.xpath31.processor.types.XSDecimal;
import xml.xpath31.processor.types.XSDouble;
import xml.xpath31.processor.types.XSFloat;
import xml.xpath31.processor.types.XSInteger;
+import xml.xpath31.processor.types.XSNumericType;
import xml.xpath31.processor.types.XSString;
/**
@@ -275,12 +277,46 @@ public class IDiv extends XPathArithmeticOp
}
}
- // Validating an XPath 3.1 operator 'idiv', operands compatibility for addition
+ if (left instanceof XSNumericType) {
+ if ((right instanceof XSString) || (right instanceof XString)) {
+ java.lang.String str2 = XslTransformEvaluationHelper.getStrVal(right);
+
+ try {
+ Integer.valueOf(str2);
+ right = new XSInteger(str2+"");
+
+ typeName2 = "integer";
+ typeNs2 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
+ }
+ catch (NumberFormatException ex) {
+ // no op
+ }
+ }
+ }
+
+ if (right instanceof XSNumericType) {
+ if ((left instanceof XSString) || (left instanceof XString)) {
+ java.lang.String str1 = XslTransformEvaluationHelper.getStrVal(left);
+
+ try {
+ Integer.valueOf(str1);
+ left = new XSInteger(str1+"");
+
+ typeName1 = "integer";
+ typeNs1 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
+ }
+ catch (NumberFormatException ex) {
+ // no op
+ }
+ }
+ }
+
+ // Validating an XPath 3.1 operator 'idiv', operands compatibility for integer division
// Ref : XPath 3.1 operator mapping, https://www.w3.org/TR/xpath-31/#mapping
if ((XMLConstants.W3C_XML_SCHEMA_NS_URI).equals(typeNs1) && (XMLConstants.W3C_XML_SCHEMA_NS_URI).equals(typeNs2)) {
if ((isXsBuiltInTypeNumeric(typeName1) && !isXsBuiltInTypeNumeric(typeName2)) ||
(isXsBuiltInTypeNumeric(typeName2) && !isXsBuiltInTypeNumeric(typeName1))) {
- throw new javax.xml.transform.TransformerException("FOTY0013 : An XPath 3.1 operator 'idiv' cannot add values of schema "
+ throw new javax.xml.transform.TransformerException("FOTY0013 : An XPath 3.1 operator 'idiv' cannot apply values of schema "
+ "types " + typeName1 + " and " + typeName2 + ".");
}
diff --git a/src/main/java/org/apache/xpath/operations/InstanceOf.java b/src/main/java/org/apache/xpath/operations/InstanceOf.java
index b2f358480..3b4986ea2 100644
--- a/src/main/java/org/apache/xpath/operations/InstanceOf.java
+++ b/src/main/java/org/apache/xpath/operations/InstanceOf.java
@@ -133,10 +133,10 @@ public class InstanceOf extends Operation
/**
* 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.
+ * @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.
+ * @return non-null reference to the XObject that represents the result of the operation
*
* @throws javax.xml.transform.TransformerException
*/
@@ -145,13 +145,29 @@ public class InstanceOf extends Operation
{
XObject result = null;
-
- StylesheetRoot stylesheetRoot = XslTransformEvaluationHelper.getXslStylesheetRootFromXslElementRef(this);
+
+ SequenceTypeData seqTypedData = null;
+
+ SequenceTypeData castAsType = left.getCastAsType();
+
+ StylesheetRoot stylesheetRoot = XslTransformEvaluationHelper.getXslStylesheetRootFromXslElementRef(this);
TransformerImpl transformerImpl = stylesheetRoot.getTransformerImpl();
XPathContext xctxt = transformerImpl.getXPathContext();
- PrefixResolver prefixResolver = xctxt.getNamespaceContext();
+ PrefixResolver prefixResolver = xctxt.getNamespaceContext();
- SequenceTypeData seqTypedData = (SequenceTypeData)right;
+ if (castAsType != null) {
+ if (castAsType.equal((SequenceTypeData)right)) {
+ result = XBoolean.S_TRUE;
+ }
+ else {
+ result = XBoolean.S_FALSE;
+ }
+
+ return result;
+ }
+ else {
+ seqTypedData = (SequenceTypeData)right;
+ }
int xsBuiltInSeqType = seqTypedData.getBuiltInSequenceType();
SequenceTypeKindTest sequenceTypeKindTest = seqTypedData.getSequenceTypeKindTest();
@@ -166,6 +182,30 @@ public class InstanceOf extends Operation
return XBoolean.S_TRUE;
}
}
+
+ if (left instanceof XSDouble) {
+ XSDouble xsDouble = (XSDouble)left;
+ double dbl = xsDouble.doubleValue();
+ if ((dbl == (int)dbl) || (dbl == (long)dbl)) {
+ return XBoolean.S_TRUE;
+ }
+ }
+
+ if (left instanceof XSFloat) {
+ XSFloat xsFloat = (XSFloat)left;
+ double fl1 = xsFloat.floatValue();
+ if ((fl1 == (int)fl1) || (fl1 == (long)fl1)) {
+ return XBoolean.S_TRUE;
+ }
+ }
+
+ if (left instanceof XSDecimal) {
+ XSDecimal xsDecimal = (XSDecimal)left;
+ double dbl = xsDecimal.doubleValue();
+ if ((dbl == (int)dbl) || (dbl == (long)dbl)) {
+ return XBoolean.S_TRUE;
+ }
+ }
}
if (left instanceof ElemFunctionItem) {
diff --git a/src/main/java/org/apache/xpath/operations/Minus.java b/src/main/java/org/apache/xpath/operations/Minus.java
index 4a8a01214..0c1e58347 100644
--- a/src/main/java/org/apache/xpath/operations/Minus.java
+++ b/src/main/java/org/apache/xpath/operations/Minus.java
@@ -50,6 +50,7 @@ import org.apache.xpath.objects.XNumber;
import org.apache.xpath.objects.XObject;
import org.apache.xpath.objects.XPathInlineFunction;
import org.apache.xpath.objects.XPathMap;
+import org.apache.xpath.objects.XString;
import org.w3c.dom.Node;
import xml.xpath31.processor.types.XSAnyAtomicType;
@@ -62,6 +63,7 @@ import xml.xpath31.processor.types.XSDouble;
import xml.xpath31.processor.types.XSFloat;
import xml.xpath31.processor.types.XSInteger;
import xml.xpath31.processor.types.XSNumericType;
+import xml.xpath31.processor.types.XSString;
import xml.xpath31.processor.types.XSTime;
import xml.xpath31.processor.types.XSUntyped;
import xml.xpath31.processor.types.XSUntypedAtomic;
@@ -338,11 +340,11 @@ public class Minus extends XPathArithmeticOp
}
else if (right instanceof XSAnyAtomicType) {
XSAnyAtomicType xsAnyAtomicType = (XSAnyAtomicType)right;
- typeName1 = xsAnyAtomicType.stringType();
+ typeName2 = xsAnyAtomicType.stringType();
- int colonIdx = typeName1.indexOf(':');
- typeName1 = typeName1.substring(colonIdx + 1);
- typeNs1 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
+ int colonIdx = typeName2.indexOf(':');
+ typeName2 = typeName2.substring(colonIdx + 1);
+ typeNs2 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
}
else if (right instanceof XNumber) {
double dbl = ((XNumber)right).num();
@@ -374,6 +376,57 @@ public class Minus extends XPathArithmeticOp
typeNs2 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
}
+ if (left instanceof XSNumericType) {
+ if ((right instanceof XSString) || (right instanceof XString)) {
+ java.lang.String str2 = XslTransformEvaluationHelper.getStrVal(right);
+
+ try {
+ double dbl2 = Double.valueOf(str2);
+ right = new XSDouble(dbl2);
+
+ typeName2 = "double";
+ typeNs2 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
+ }
+ catch (NumberFormatException ex) {
+ // no op
+ }
+ }
+ }
+
+ if (right instanceof XSNumericType) {
+ if ((left instanceof XSString) || (left instanceof XString)) {
+ java.lang.String str1 = XslTransformEvaluationHelper.getStrVal(left);
+
+ try {
+ double dbl1 = Double.valueOf(str1);
+ left = new XSDouble(dbl1);
+
+ typeName1 = "double";
+ typeNs1 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
+ }
+ catch (NumberFormatException ex) {
+ // no op
+ }
+ }
+ }
+
+ if ((right instanceof XSUntypedAtomic) || (right instanceof XSUntyped)) {
+ if ((left instanceof XSNumericType) || (left instanceof XNumber)) {
+ java.lang.String str2 = XslTransformEvaluationHelper.getStrVal(right);
+
+ try {
+ double dbl2 = Double.valueOf(str2);
+ right = new XSDouble(dbl2);
+
+ typeName2 = "double";
+ typeNs2 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
+ }
+ catch (NumberFormatException ex) {
+ // no op
+ }
+ }
+ }
+
// Validating an XPath 3.1 operator '-', operands compatibility for subtraction
// Ref : XPath 3.1 operator mapping, https://www.w3.org/TR/xpath-31/#mapping
if ((XMLConstants.W3C_XML_SCHEMA_NS_URI).equals(typeNs1) && (XMLConstants.W3C_XML_SCHEMA_NS_URI).equals(typeNs2)) {
diff --git a/src/main/java/org/apache/xpath/operations/Mod.java b/src/main/java/org/apache/xpath/operations/Mod.java
index 73b078b55..cd13330b8 100644
--- a/src/main/java/org/apache/xpath/operations/Mod.java
+++ b/src/main/java/org/apache/xpath/operations/Mod.java
@@ -48,11 +48,13 @@ import org.apache.xpath.objects.XNumber;
import org.apache.xpath.objects.XObject;
import org.apache.xpath.objects.XPathInlineFunction;
import org.apache.xpath.objects.XPathMap;
+import org.apache.xpath.objects.XString;
import org.w3c.dom.Node;
import xml.xpath31.processor.types.XSDecimal;
import xml.xpath31.processor.types.XSDouble;
import xml.xpath31.processor.types.XSNumericType;
+import xml.xpath31.processor.types.XSString;
import xml.xpath31.processor.types.XSUntyped;
import xml.xpath31.processor.types.XSUntypedAtomic;
import xml.xpath31.processor.types.XSYearMonthDuration;
@@ -277,12 +279,46 @@ public class Mod extends XPathArithmeticOp
}
}
- // Validating an XPath 3.1 operator 'mod', operands compatibility for mod
+ if (left instanceof XSNumericType) {
+ if ((right instanceof XSString) || (right instanceof XString)) {
+ java.lang.String str2 = XslTransformEvaluationHelper.getStrVal(right);
+
+ try {
+ double dbl2 = Double.valueOf(str2);
+ right = new XSDouble(dbl2);
+
+ typeName2 = "double";
+ typeNs2 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
+ }
+ catch (NumberFormatException ex) {
+ // no op
+ }
+ }
+ }
+
+ if (right instanceof XSNumericType) {
+ if ((left instanceof XSString) || (left instanceof XString)) {
+ java.lang.String str1 = XslTransformEvaluationHelper.getStrVal(left);
+
+ try {
+ double dbl1 = Double.valueOf(str1);
+ left = new XSDouble(dbl1);
+
+ typeName2 = "double";
+ typeNs2 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
+ }
+ catch (NumberFormatException ex) {
+ // no op
+ }
+ }
+ }
+
+ // Validating an XPath 3.1 operator 'mod', operands compatibility for computing modulus
// Ref : XPath 3.1 operator mapping, https://www.w3.org/TR/xpath-31/#mapping
if ((XMLConstants.W3C_XML_SCHEMA_NS_URI).equals(typeNs1) && (XMLConstants.W3C_XML_SCHEMA_NS_URI).equals(typeNs2)) {
if ((isXsBuiltInTypeNumeric(typeName1) && !isXsBuiltInTypeNumeric(typeName2)) ||
(isXsBuiltInTypeNumeric(typeName2) && !isXsBuiltInTypeNumeric(typeName1))) {
- throw new javax.xml.transform.TransformerException("FOTY0013 : An XPath 3.1 operator 'mod' cannot add values of schema "
+ throw new javax.xml.transform.TransformerException("FOTY0013 : An XPath 3.1 operator 'mod' cannot apply values of schema "
+ "types " + typeName1 + " and " + typeName2 + ".");
}
diff --git a/src/main/java/org/apache/xpath/operations/Mult.java b/src/main/java/org/apache/xpath/operations/Mult.java
index fbc7977bb..a62858ece 100644
--- a/src/main/java/org/apache/xpath/operations/Mult.java
+++ b/src/main/java/org/apache/xpath/operations/Mult.java
@@ -51,6 +51,7 @@ import org.apache.xpath.objects.XNumber;
import org.apache.xpath.objects.XObject;
import org.apache.xpath.objects.XPathInlineFunction;
import org.apache.xpath.objects.XPathMap;
+import org.apache.xpath.objects.XString;
import org.w3c.dom.Node;
import xml.xpath31.processor.types.XSAnyAtomicType;
@@ -61,6 +62,7 @@ import xml.xpath31.processor.types.XSDouble;
import xml.xpath31.processor.types.XSFloat;
import xml.xpath31.processor.types.XSInteger;
import xml.xpath31.processor.types.XSNumericType;
+import xml.xpath31.processor.types.XSString;
import xml.xpath31.processor.types.XSUntyped;
import xml.xpath31.processor.types.XSUntypedAtomic;
import xml.xpath31.processor.types.XSYearMonthDuration;
@@ -272,6 +274,24 @@ public class Mult extends XPathArithmeticOp
typeNs1 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
}
+ if (((left instanceof XSString) || (left instanceof XString)) &&
+ (right instanceof XSDayTimeDuration)) {
+ // Written to solve use cases like, W3C XSLT 3.0 test suite, test case type\date\date-055
+
+ java.lang.String str1 = XslTransformEvaluationHelper.getStrVal(left);
+
+ try {
+ Double dbl = Double.valueOf(str1);
+ left = new XSDouble(dbl);
+
+ typeName1 = "double";
+ typeNs1 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
+ }
+ catch (NumberFormatException ex) {
+ // no op
+ }
+ }
+
java.lang.String typeName2 = null;
java.lang.String typeNs2 = null;
@@ -351,11 +371,11 @@ public class Mult extends XPathArithmeticOp
}
else if (right instanceof XSAnyAtomicType) {
XSAnyAtomicType xsAnyAtomicType = (XSAnyAtomicType)right;
- typeName1 = xsAnyAtomicType.stringType();
+ typeName2 = xsAnyAtomicType.stringType();
- int colonIdx = typeName1.indexOf(':');
- typeName1 = typeName1.substring(colonIdx + 1);
- typeNs1 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
+ int colonIdx = typeName2.indexOf(':');
+ typeName2 = typeName2.substring(colonIdx + 1);
+ typeNs2 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
}
else if (right instanceof XNumber) {
double dbl = ((XNumber)right).num();
@@ -371,6 +391,24 @@ public class Mult extends XPathArithmeticOp
typeNs2 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
}
+ if (((right instanceof XSString) || (right instanceof XString)) &&
+ (left instanceof XSDayTimeDuration)) {
+ // Written to solve use cases like, W3C XSLT 3.0 test suite, test case type\date\date-055
+
+ java.lang.String str1 = XslTransformEvaluationHelper.getStrVal(right);
+
+ try {
+ Double dbl = Double.valueOf(str1);
+ right = new XSDouble(dbl);
+
+ typeName2 = "double";
+ typeNs2 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
+ }
+ catch (NumberFormatException ex) {
+ // no op
+ }
+ }
+
if (left instanceof XSFloat) {
float fl1 = ((XSFloat)left).floatValue();
left = new XSDouble(fl1);
@@ -412,24 +450,69 @@ public class Mult extends XPathArithmeticOp
}
}
+ if (left instanceof XSNumericType) {
+ if ((right instanceof XSString) || (right instanceof XString)) {
+ java.lang.String str2 = XslTransformEvaluationHelper.getStrVal(right);
+
+ try {
+ double dbl2 = Double.valueOf(str2);
+ right = new XSDouble(dbl2);
+
+ typeName2 = "double";
+ typeNs2 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
+ }
+ catch (NumberFormatException ex) {
+ // no op
+ }
+ }
+ }
+
+ if (right instanceof XSNumericType) {
+ if ((left instanceof XSString) || (left instanceof XString)) {
+ java.lang.String str1 = XslTransformEvaluationHelper.getStrVal(left);
+
+ try {
+ double dbl1 = Double.valueOf(str1);
+ left = new XSDouble(dbl1);
+
+ typeName1 = "double";
+ typeNs1 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
+ }
+ catch (NumberFormatException ex) {
+ // no op
+ }
+ }
+ }
+
+ if ((right instanceof XSUntypedAtomic) || (right instanceof XSUntyped)) {
+ if ((left instanceof XSNumericType) || (left instanceof XNumber)) {
+ java.lang.String str2 = XslTransformEvaluationHelper.getStrVal(right);
+
+ try {
+ double dbl2 = Double.valueOf(str2);
+ right = new XSDouble(dbl2);
+
+ typeName2 = "double";
+ typeNs2 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
+ }
+ catch (NumberFormatException ex) {
+ // no op
+ }
+ }
+ }
+
// Validating an XPath 3.1 operator '*', operands compatibility for multiplication
// Ref : XPath 3.1 operator mapping, https://www.w3.org/TR/xpath-31/#mapping
if ((XMLConstants.W3C_XML_SCHEMA_NS_URI).equals(typeNs1) && (XMLConstants.W3C_XML_SCHEMA_NS_URI).equals(typeNs2)) {
- if (("yearMonthDuration".equals(typeName1) || isXsBuiltInTypeNumeric(typeName1)) && !isXsBuiltInTypeNumeric(typeName2)) {
+ if (isXsBuiltInTypeNumeric(typeName1) && !(isXsBuiltInTypeNumeric(typeName2) ||
+ "yearMonthDuration".equals(typeName2) ||
+ "dayTimeDuration".equals(typeName2))) {
throw new javax.xml.transform.TransformerException("FOTY0013 : An XPath 3.1 operator '*' cannot multiply schema "
- + "type " + typeName1 + " value with " + typeName2 + ".");
+ + "type " + typeName1 + " value with " + typeName2 + ".");
}
- else if (isXsBuiltInTypeNumeric(typeName1) && !("yearMonthDuration".equals(typeName2) || isXsBuiltInTypeNumeric(typeName2))) {
- throw new javax.xml.transform.TransformerException("FOTY0013 : An XPath 3.1 operator '*' cannot multiply schema "
- + "type " + typeName1 + " value with " + typeName2 + ".");
- }
- else if (("dayTimeDuration".equals(typeName1) || isXsBuiltInTypeNumeric(typeName1)) && !isXsBuiltInTypeNumeric(typeName2)) {
- throw new javax.xml.transform.TransformerException("FOTY0013 : An XPath 3.1 operator '*' cannot multiply schema "
- + "type " + typeName1 + " value with " + typeName2 + ".");
- }
- else if (isXsBuiltInTypeNumeric(typeName1) && !("dayTimeDuration".equals(typeName2) || isXsBuiltInTypeNumeric(typeName2))) {
- throw new javax.xml.transform.TransformerException("FOTY0013 : An XPath 3.1 operator '*' cannot multiply schema "
- + "type " + typeName1 + " value with " + typeName2 + ".");
+ else if (("yearMonthDuration".equals(typeName1) || "dayTimeDuration".equals(typeName1)) && !isXsBuiltInTypeNumeric(typeName2)) {
+ throw new javax.xml.transform.TransformerException("FOTY0013 : An XPath 3.1 operator '-' cannot subtract schema "
+ + "type " + typeName1 + " value from " + typeName2 + ".");
}
List<XMLNSDecl> nsPrefixTable = stylesheetRoot.getPrefixTable();
diff --git a/src/main/java/org/apache/xpath/operations/Plus.java b/src/main/java/org/apache/xpath/operations/Plus.java
index 2bf905f9d..b728a5972 100644
--- a/src/main/java/org/apache/xpath/operations/Plus.java
+++ b/src/main/java/org/apache/xpath/operations/Plus.java
@@ -50,6 +50,7 @@ import org.apache.xpath.objects.XNumber;
import org.apache.xpath.objects.XObject;
import org.apache.xpath.objects.XPathInlineFunction;
import org.apache.xpath.objects.XPathMap;
+import org.apache.xpath.objects.XString;
import org.w3c.dom.Node;
import xml.xpath31.processor.types.XSAnyAtomicType;
@@ -62,6 +63,7 @@ import xml.xpath31.processor.types.XSDouble;
import xml.xpath31.processor.types.XSFloat;
import xml.xpath31.processor.types.XSInteger;
import xml.xpath31.processor.types.XSNumericType;
+import xml.xpath31.processor.types.XSString;
import xml.xpath31.processor.types.XSTime;
import xml.xpath31.processor.types.XSUntyped;
import xml.xpath31.processor.types.XSUntypedAtomic;
@@ -353,11 +355,11 @@ public class Plus extends XPathArithmeticOp
}
else if (right instanceof XSAnyAtomicType) {
XSAnyAtomicType xsAnyAtomicType = (XSAnyAtomicType)right;
- typeName1 = xsAnyAtomicType.stringType();
+ typeName2 = xsAnyAtomicType.stringType();
- int colonIdx = typeName1.indexOf(':');
- typeName1 = typeName1.substring(colonIdx + 1);
- typeNs1 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
+ int colonIdx = typeName2.indexOf(':');
+ typeName2 = typeName2.substring(colonIdx + 1);
+ typeNs2 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
}
else if (right instanceof XNumber) {
double dbl = ((XNumber)right).num();
@@ -414,6 +416,57 @@ public class Plus extends XPathArithmeticOp
}
}
+ if (left instanceof XSNumericType) {
+ if ((right instanceof XSString) || (right instanceof XString)) {
+ java.lang.String str2 = XslTransformEvaluationHelper.getStrVal(right);
+
+ try {
+ double dbl2 = Double.valueOf(str2);
+ right = new XSDouble(dbl2);
+
+ typeName2 = "double";
+ typeNs2 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
+ }
+ catch (NumberFormatException ex) {
+ // no op
+ }
+ }
+ }
+
+ if (right instanceof XSNumericType) {
+ if ((left instanceof XSString) || (left instanceof XString)) {
+ java.lang.String str1 = XslTransformEvaluationHelper.getStrVal(left);
+
+ try {
+ double dbl1 = Double.valueOf(str1);
+ left = new XSDouble(dbl1);
+
+ typeName1 = "double";
+ typeNs1 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
+ }
+ catch (NumberFormatException ex) {
+ // no op
+ }
+ }
+ }
+
+ if ((right instanceof XSUntypedAtomic) || (right instanceof XSUntyped)) {
+ if ((left instanceof XSNumericType) || (left instanceof XNumber)) {
+ java.lang.String str2 = XslTransformEvaluationHelper.getStrVal(right);
+
+ try {
+ double dbl2 = Double.valueOf(str2);
+ right = new XSDouble(dbl2);
+
+ typeName2 = "double";
+ typeNs2 = XMLConstants.W3C_XML_SCHEMA_NS_URI;
+ }
+ catch (NumberFormatException ex) {
+ // no op
+ }
+ }
+ }
+
// Validating an XPath 3.1 operator '+', operands compatibility for addition
// Ref : XPath 3.1 operator mapping, https://www.w3.org/TR/xpath-31/#mapping
if ((XMLConstants.W3C_XML_SCHEMA_NS_URI).equals(typeNs1) && (XMLConstants.W3C_XML_SCHEMA_NS_URI).equals(typeNs2)) {
@@ -431,7 +484,9 @@ public class Plus extends XPathArithmeticOp
+ "types " + typeName1 + " and " + typeName2 + ".");
}
else if (("time".equals(typeName1) && !"dayTimeDuration".equals(typeName2)) ||
- ("dayTimeDuration".equals(typeName1) && !"time".equals(typeName2))) {
+ ("dayTimeDuration".equals(typeName1) && !("date".equals(typeName2) || "time".equals(typeName2) ||
+ "dateTime".equals(typeName2) ||
+ "dayTimeDuration".equals(typeName2)))) {
throw new javax.xml.transform.TransformerException("FOTY0013 : An XPath 3.1 operator '+' cannot add values of schema "
+ "types " + typeName1 + " and " + typeName2 + ".");
}
@@ -443,8 +498,11 @@ public class Plus extends XPathArithmeticOp
throw new javax.xml.transform.TransformerException("FOTY0013 : An XPath 3.1 operator '+' cannot add values of schema "
+ "types " + typeName1 + " and " + typeName2 + ".");
}
- else if (("yearMonthDuration".equals(typeName1) && !"yearMonthDuration".equals(typeName2)) ||
- ("dayTimeDuration".equals(typeName1) && !"dayTimeDuration".equals(typeName2))) {
+ else if (("yearMonthDuration".equals(typeName1) && !("date".equals(typeName2) || "dateTime".equals(typeName2) ||
+ "yearMonthDuration".equals(typeName2))) ||
+ ("dayTimeDuration".equals(typeName1) && !("date".equals(typeName2) || "time".equals(typeName2) ||
+ "dateTime".equals(typeName2) ||
+ "dayTimeDuration".equals(typeName2)))) {
throw new javax.xml.transform.TransformerException("FOTY0013 : An XPath 3.1 operator '+' cannot add values of schema "
+ "types " + typeName1 + " and " + typeName2 + ".");
}
diff --git a/src/test/java/org/apache/xalan/tests/main/XalanXsl3TestSuite2.java b/src/test/java/org/apache/xalan/tests/main/XalanXsl3TestSuite2.java
index 4cc580fc7..26bd23504 100644
--- a/src/test/java/org/apache/xalan/tests/main/XalanXsl3TestSuite2.java
+++ b/src/test/java/org/apache/xalan/tests/main/XalanXsl3TestSuite2.java
@@ -71,6 +71,7 @@ import org.apache.xalan.tests.xpath3.XPathTextAndNodePattern;
import org.apache.xalan.tests.xpath3.XPathUriQualifiedNameTests;
import org.apache.xalan.tests.xpath3.XsDurationComponentExtractionFunctionTests;
import org.apache.xalan.tests.xpath3.XsGregorianTypeTests;
+import org.apache.xalan.tests.xpath3.XslSchemaAwareTests;
import org.apache.xalan.tests.xslt3.XalanJavaExtensionTests;
import org.apache.xalan.tests.xslt3.XalanJavascriptExtensionTests;
import org.apache.xalan.tests.xslt3.XslCharacterMapTests;
@@ -157,7 +158,7 @@ import xml.xpath31.processor.types.tests.XSTimeTest;
XslUseAttributeSetsTests.class, XslInitialFunctionTests.class, XslFnCopyofTests.class, FnUnparsedTextAvailableTests.class,
XslMapTests.class, FnSerializeTests.class, XPath3DecimalFormatTest.class, XSAnyURITest.class, XSDateTest.class,
XSDateTimeTest.class, XSDayTimeDurationTest.class, XSDecimalTest.class, XSDoubleTest.class, XSDurationTest.class,
- XSNumericTypeTest.class, XSTimeTest.class, FnFormatDateTests.class, FnParseIetfDateTests.class })
+ XSNumericTypeTest.class, XSTimeTest.class, FnFormatDateTests.class, FnParseIetfDateTests.class, XslSchemaAwareTests.class })
public class XalanXsl3TestSuite2 {
}
diff --git a/src/test/java/org/apache/xalan/tests/util/XslTransformTestsUtil.java b/src/test/java/org/apache/xalan/tests/util/XslTransformTestsUtil.java
index f04e7567e..76f16bcaa 100644
--- a/src/test/java/org/apache/xalan/tests/util/XslTransformTestsUtil.java
+++ b/src/test/java/org/apache/xalan/tests/util/XslTransformTestsUtil.java
@@ -147,9 +147,9 @@ public class XslTransformTestsUtil extends FileComparisonUtil {
m_xslTransformerFactory.setAttribute(XalanProperties.INIT_MODE, m_initModeName);
}
- StreamSource xsltStreamSrc = new StreamSource(xslDocumentUriStr);
+ StreamSource xslStreamSrc = new StreamSource(xslDocumentUriStr);
- Transformer transformer = m_xslTransformerFactory.newTransformer(xsltStreamSrc);
+ Transformer transformer = m_xslTransformerFactory.newTransformer(xslStreamSrc);
setXslTransformProperties(transformer);
diff --git a/src/test/java/org/apache/xalan/tests/xpath3/XslSchemaAwareTests.java b/src/test/java/org/apache/xalan/tests/xpath3/XslSchemaAwareTests.java
new file mode 100644
index 000000000..c7f51b0b1
--- /dev/null
+++ b/src/test/java/org/apache/xalan/tests/xpath3/XslSchemaAwareTests.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.xalan.tests.xpath3;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.StringWriter;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.xalan.templates.Constants;
+import org.apache.xalan.tests.util.FileComparisonUtil;
+import org.apache.xalan.tests.util.XSLTestConstants;
+import org.apache.xerces.parsers.DOMParser;
+import org.apache.xml.utils.DefaultErrorHandler;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+
+import junit.framework.Assert;
+
+/**
+ * XSL 3 stylesheet test cases, to test XPath 3.1 schema
+ * aware feature.
+ *
+ * @author Mukul Gandhi <mu...@apache.org>
+ *
+ * @xsl.usage advanced
+ */
+public class XslSchemaAwareTests extends FileComparisonUtil {
+
+ private static final String XSL_TRANSFORM_INPUT_DIRPATH = XSLTestConstants.XSL_TRANSFORM_INPUT_DIRPATH_PREFIX + "xsl_schema_aware/";
+
+ private static TransformerFactory m_xslTransformerFactory = null;
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ System.setProperty(Constants.XML_DOCUMENT_BUILDER_FACTORY_KEY, Constants.XML_DOCUMENT_BUILDER_FACTORY_VALUE);
+ System.setProperty(Constants.XSL_TRANSFORM_FACTORY_KEY, Constants.XSL_TRANSFORM_FACTORY_VALUE);
+
+ m_xslTransformerFactory = TransformerFactory.newInstance();
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception {
+ // no op
+ }
+
+ @Test
+ public void xslSchemaAwareTest1() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xml";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl";
+
+ InputSource inpSrc = new InputSource(xmlFilePath);
+
+ TransformerFactory tfactory = TransformerFactory.newInstance();
+ tfactory.setErrorListener(new DefaultErrorHandler(true));
+
+ try {
+ String xslDocumentUriStr = ((new File(xslFilePath)).toURI()).toString();
+ StreamSource xslStreamSrc = new StreamSource(xslDocumentUriStr);
+
+ Transformer transformer = m_xslTransformerFactory.newTransformer(xslStreamSrc);
+
+ DOMParser parser = new DOMParser();
+ parser.setFeature(Constants.XML_VALIDATION_FEATURE, true);
+ parser.setFeature(Constants.XML_SCHEMA_VALIDATION_FEATURE, true);
+ parser.setFeature(Constants.XML_SCHEMA_FULL_CHECKING_FEATURE, true);
+
+ parser.setProperty(Constants.XML_DOM_DOCUMENT_CLASS_NAME, Constants.XERCES_PSVI_DOCUMENT_IMPL);
+
+ parser.parse(inpSrc);
+ Document document = parser.getDocument();
+
+ DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
+ dfactory.setCoalescing(true);
+ dfactory.setNamespaceAware(true);
+
+ StringWriter resultStrWriter = new StringWriter();
+ StreamResult streamResult = new StreamResult(resultStrWriter);
+
+ transformer.transform(new DOMSource(document, xmlFilePath), streamResult);
+
+ String actualResultStr = resultStrWriter.toString();
+
+ String expectedResultStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><result>\n"
+ + " <one isInteger=\"true\">7</one>\n"
+ + " <two isDate=\"true\">2010-11-15</two>\n"
+ + "</result>\n";
+
+ boolean isTestPass = isXMLFileContentsEqual(actualResultStr, expectedResultStr);
+
+ assertTrue(isTestPass);
+ }
+ catch (Exception ex) {
+ Assert.fail();
+ }
+ }
+
+}
diff --git a/src/test/resources/xsl_schema_aware/test1.xml b/src/test/resources/xsl_schema_aware/test1.xml
new file mode 100644
index 000000000..8d0c17ccc
--- /dev/null
+++ b/src/test/resources/xsl_schema_aware/test1.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<person xsi:noNamespaceSchemaLocation="test1.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <id>2</id>
+ <name>mukul</name>
+ <dob>2005-10-15</dob>
+</person>
diff --git a/src/test/resources/xsl_schema_aware/test1.xsd b/src/test/resources/xsl_schema_aware/test1.xsd
new file mode 100644
index 000000000..179e4cb48
--- /dev/null
+++ b/src/test/resources/xsl_schema_aware/test1.xsd
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <xs:element name="person" type="PersonType"/>
+
+ <xs:complexType name="PersonType">
+ <xs:sequence>
+ <xs:element name="id" type="xs:integer"/>
+ <xs:element name="name" type="xs:string"/>
+ <xs:element name="dob" type="xs:date"/>
+ </xs:sequence>
+ </xs:complexType>
+
+</xs:schema>
\ No newline at end of file
diff --git a/src/test/resources/xsl_schema_aware/test1.xsl b/src/test/resources/xsl_schema_aware/test1.xsl
new file mode 100644
index 000000000..7e818724f
--- /dev/null
+++ b/src/test/resources/xsl_schema_aware/test1.xsl
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ exclude-result-prefixes="xs"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- use with test1.xml -->
+
+ <!-- An XSL 3 stylesheet test case, to test XPath 3.1 schema aware feature -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:template match="/">
+ <result>
+ <xsl:variable name="value1" select="person/id + 5"/>
+ <one isInteger="{$value1 instance of xs:integer}"><xsl:value-of select="$value1"/></one>
+ <xsl:variable name="date2" select="person/dob + xs:yearMonthDuration('P5Y1M')"/>
+ <two isDate="{$date2 instance of xs:date}"><xsl:value-of select="$date2"/></two>
+ </result>
+ </xsl:template>
+
+ <!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+</xsl:stylesheet>
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xalan.apache.org
For additional commands, e-mail: commits-help@xalan.apache.org