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 2024/08/10 16:33:47 UTC
(xalan-java) branch xalan-j_xslt3.0 updated: improving implementation of xpath path expression having function call suffix (jira issue XALANJ-2773), along with few conformance tests for these modifications. there are various related code refactoring as well.
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 f0ca2785d improving implementation of xpath path expression having function call suffix (jira issue XALANJ-2773), along with few conformance tests for these modifications. there are various related code refactoring as well.
f0ca2785d is described below
commit f0ca2785d68b9d3ff81311e1f8c3ea74e3ccabce
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Sat Aug 10 22:03:32 2024 +0530
improving implementation of xpath path expression having function call suffix (jira issue XALANJ-2773), along with few conformance tests for these modifications. there are various related code refactoring as well.
---
.../apache/xalan/processor/StylesheetHandler.java | 14 +
src/org/apache/xalan/templates/ElemForEach.java | 8 +-
src/org/apache/xalan/templates/ElemIterate.java | 10 +-
src/org/apache/xalan/templates/ElemValueOf.java | 8 +-
src/org/apache/xalan/templates/ElemVariable.java | 12 +-
src/org/apache/xml/utils/NamespaceSupport2.java | 13 +-
src/org/apache/xpath/XPath.java | 21 +-
src/org/apache/xpath/axes/LocPathIterator.java | 16 +
src/org/apache/xpath/axes/WalkingIterator.java | 16 -
src/org/apache/xpath/compiler/XPathParser.java | 22 +-
.../apache/xpath/composite/LetExprVarBinding.java | 18 +-
src/org/apache/xpath/composite/XPathLetExpr.java | 40 +-
src/org/apache/xpath/functions/FuncLocalName.java | 49 +-
src/org/apache/xpath/functions/FuncName.java | 66 ++-
.../apache/xpath/functions/FunctionDef1Arg.java | 17 +-
.../apache/xpath/functions/XSLFunctionService.java | 610 +++++++++------------
.../xpath3/XPathExprFunctionCallSuffixTests.java | 70 +++
tests/xpath_function_call_suffix/gold/test10.out | 13 +
tests/xpath_function_call_suffix/gold/test11.out | 13 +
tests/xpath_function_call_suffix/gold/test5.out | 7 +
tests/xpath_function_call_suffix/gold/test6.out | 7 +
tests/xpath_function_call_suffix/gold/test7.out | 7 +
tests/xpath_function_call_suffix/gold/test8.out | 7 +
tests/xpath_function_call_suffix/gold/test9.out | 7 +
tests/xpath_function_call_suffix/test10.xsl | 42 ++
tests/xpath_function_call_suffix/test11.xsl | 43 ++
tests/xpath_function_call_suffix/test2.xml | 8 +
tests/xpath_function_call_suffix/test3.xml | 8 +
tests/xpath_function_call_suffix/test5.xsl | 47 ++
tests/xpath_function_call_suffix/test6.xsl | 48 ++
tests/xpath_function_call_suffix/test7.xsl | 44 ++
tests/xpath_function_call_suffix/test8.xsl | 52 ++
tests/xpath_function_call_suffix/test9.xsl | 48 ++
33 files changed, 965 insertions(+), 446 deletions(-)
diff --git a/src/org/apache/xalan/processor/StylesheetHandler.java b/src/org/apache/xalan/processor/StylesheetHandler.java
index a563c2335..156c4b632 100644
--- a/src/org/apache/xalan/processor/StylesheetHandler.java
+++ b/src/org/apache/xalan/processor/StylesheetHandler.java
@@ -20,6 +20,7 @@
*/
package org.apache.xalan.processor;
+import java.util.Hashtable;
import java.util.Stack;
import javax.xml.transform.ErrorListener;
@@ -1577,6 +1578,19 @@ public class StylesheetHandler extends DefaultHandler
{
return (NamespaceSupport) m_nsSupportStack.peek();
}
+
+ /**
+ * Get the namespace declaration table, in the current
+ * stylesheet context.
+ */
+ public Hashtable getNamespaceUriTable() {
+ Hashtable nsUriTable = null;
+
+ NamespaceSupport2 nsSupport = (NamespaceSupport2)m_nsSupportStack.peek();
+ nsUriTable = nsSupport.getUriTable();
+
+ return nsUriTable;
+ }
/**
* The originating node if the current stylesheet is being created
diff --git a/src/org/apache/xalan/templates/ElemForEach.java b/src/org/apache/xalan/templates/ElemForEach.java
index d7327d17e..9b0ee5d52 100644
--- a/src/org/apache/xalan/templates/ElemForEach.java
+++ b/src/org/apache/xalan/templates/ElemForEach.java
@@ -41,7 +41,6 @@ import org.apache.xpath.ExpressionOwner;
import org.apache.xpath.XPath;
import org.apache.xpath.XPathContext;
import org.apache.xpath.axes.LocPathIterator;
-import org.apache.xpath.axes.WalkingIterator;
import org.apache.xpath.composite.XPathForExpr;
import org.apache.xpath.composite.XPathSequenceConstructor;
import org.apache.xpath.functions.Function;
@@ -449,12 +448,7 @@ public class ElemForEach extends ElemTemplateElement implements ExpressionOwner
else if (m_selectExpression instanceof LocPathIterator) {
LocPathIterator locPathIterator = (LocPathIterator)m_selectExpression;
- Function func = null;
-
- if (locPathIterator instanceof WalkingIterator) {
- WalkingIterator walkingIter = (WalkingIterator)locPathIterator;
- func = walkingIter.getFuncExpr();
- }
+ Function func = locPathIterator.getFuncExpr();
boolean isProcessAsNodeset = true;
DTMIterator dtmIter = null;
diff --git a/src/org/apache/xalan/templates/ElemIterate.java b/src/org/apache/xalan/templates/ElemIterate.java
index 87ea932d7..ea3c97cf8 100644
--- a/src/org/apache/xalan/templates/ElemIterate.java
+++ b/src/org/apache/xalan/templates/ElemIterate.java
@@ -32,7 +32,7 @@ import org.apache.xpath.Expression;
import org.apache.xpath.ExpressionOwner;
import org.apache.xpath.XPath;
import org.apache.xpath.XPathContext;
-import org.apache.xpath.axes.WalkingIterator;
+import org.apache.xpath.axes.LocPathIterator;
import org.apache.xpath.functions.Function;
import org.apache.xpath.objects.ResultSequence;
import org.apache.xpath.objects.XNodeSet;
@@ -186,13 +186,13 @@ public class ElemIterate extends ElemTemplateElement implements ExpressionOwner
Function func = null;
- if (m_selectExpression instanceof WalkingIterator) {
- WalkingIterator walkingIter = (WalkingIterator)m_selectExpression;
- func = walkingIter.getFuncExpr();
+ if (m_selectExpression instanceof LocPathIterator) {
+ LocPathIterator locPathIter = (LocPathIterator)m_selectExpression;
+ func = locPathIter.getFuncExpr();
DTMIterator dtmIter = null;
try {
- dtmIter = walkingIter.asIterator(xctxt, sourceNode);
+ dtmIter = locPathIter.asIterator(xctxt, sourceNode);
}
catch (ClassCastException ex) {
// no op
diff --git a/src/org/apache/xalan/templates/ElemValueOf.java b/src/org/apache/xalan/templates/ElemValueOf.java
index d45fdccb6..c530c8034 100644
--- a/src/org/apache/xalan/templates/ElemValueOf.java
+++ b/src/org/apache/xalan/templates/ElemValueOf.java
@@ -33,7 +33,6 @@ import org.apache.xpath.Expression;
import org.apache.xpath.XPath;
import org.apache.xpath.XPathContext;
import org.apache.xpath.axes.LocPathIterator;
-import org.apache.xpath.axes.WalkingIterator;
import org.apache.xpath.composite.XPathIfExpr;
import org.apache.xpath.composite.XPathLetExpr;
import org.apache.xpath.functions.Function;
@@ -461,12 +460,7 @@ public class ElemValueOf extends ElemTemplateElement {
else if (expr instanceof LocPathIterator) {
LocPathIterator locPathIterator = (LocPathIterator)expr;
- Function func = null;
-
- if (locPathIterator instanceof WalkingIterator) {
- WalkingIterator walkingIter = (WalkingIterator)locPathIterator;
- func = walkingIter.getFuncExpr();
- }
+ Function func = locPathIterator.getFuncExpr();;
DTMIterator dtmIter = null;
try {
diff --git a/src/org/apache/xalan/templates/ElemVariable.java b/src/org/apache/xalan/templates/ElemVariable.java
index 11393093e..cf69f5a32 100644
--- a/src/org/apache/xalan/templates/ElemVariable.java
+++ b/src/org/apache/xalan/templates/ElemVariable.java
@@ -37,19 +37,18 @@ import org.apache.xpath.XPath;
import org.apache.xpath.XPathContext;
import org.apache.xpath.axes.LocPathIterator;
import org.apache.xpath.axes.SelfIteratorNoPredicate;
-import org.apache.xpath.axes.WalkingIterator;
import org.apache.xpath.composite.SequenceTypeData;
import org.apache.xpath.composite.SequenceTypeSupport;
-import org.apache.xpath.functions.XSLConstructorStylesheetOrExtensionFunction;
import org.apache.xpath.functions.Function;
+import org.apache.xpath.functions.XSLConstructorStylesheetOrExtensionFunction;
import org.apache.xpath.functions.XSLFunctionService;
-import org.apache.xpath.objects.XPathInlineFunction;
import org.apache.xpath.objects.ResultSequence;
import org.apache.xpath.objects.XNodeSet;
import org.apache.xpath.objects.XNodeSetForDOM;
import org.apache.xpath.objects.XNumber;
import org.apache.xpath.objects.XObject;
import org.apache.xpath.objects.XPathArray;
+import org.apache.xpath.objects.XPathInlineFunction;
import org.apache.xpath.objects.XPathMap;
import org.apache.xpath.objects.XRTreeFrag;
import org.apache.xpath.objects.XRTreeFragSelectWrapper;
@@ -486,12 +485,7 @@ public class ElemVariable extends ElemTemplateElement
LocPathIterator locPathIterator = (LocPathIterator)selectExpression;
- Function func = null;
-
- if (locPathIterator instanceof WalkingIterator) {
- WalkingIterator walkingIter = (WalkingIterator)locPathIterator;
- func = walkingIter.getFuncExpr();
- }
+ Function func = locPathIterator.getFuncExpr();
DTMIterator dtmIter = null;
try {
diff --git a/src/org/apache/xml/utils/NamespaceSupport2.java b/src/org/apache/xml/utils/NamespaceSupport2.java
index 2df4c3a8b..5e1a3a50a 100644
--- a/src/org/apache/xml/utils/NamespaceSupport2.java
+++ b/src/org/apache/xml/utils/NamespaceSupport2.java
@@ -369,8 +369,13 @@ public class NamespaceSupport2
return currentContext.getDeclaredPrefixes();
}
-
-
+ /**
+ * Get namespace prefix and uri mapping table.
+ */
+ public Hashtable getUriTable() {
+ return currentContext.getUriTable();
+ }
+
}
////////////////////////////////////////////////////////////////////
@@ -743,6 +748,10 @@ final class Context2 {
tablesDirty = true;
}
+ public Hashtable getUriTable() {
+ return uriTable;
+ }
+
}
diff --git a/src/org/apache/xpath/XPath.java b/src/org/apache/xpath/XPath.java
index 8c132ca78..4fee41efe 100644
--- a/src/org/apache/xpath/XPath.java
+++ b/src/org/apache/xpath/XPath.java
@@ -18,6 +18,8 @@
package org.apache.xpath;
import java.io.Serializable;
+import java.util.Enumeration;
+import java.util.Hashtable;
import java.util.List;
import java.util.Vector;
@@ -25,6 +27,7 @@ import javax.xml.transform.ErrorListener;
import javax.xml.transform.SourceLocator;
import javax.xml.transform.TransformerException;
+import org.apache.xalan.processor.StylesheetHandler;
import org.apache.xalan.res.XSLMessages;
import org.apache.xalan.templates.ElemTemplateElement;
import org.apache.xalan.templates.XMLNSDecl;
@@ -34,7 +37,6 @@ import org.apache.xml.dtm.DTMIterator;
import org.apache.xml.utils.PrefixResolver;
import org.apache.xml.utils.SAXSourceLocator;
import org.apache.xpath.axes.LocPathIterator;
-import org.apache.xpath.axes.WalkingIterator;
import org.apache.xpath.compiler.Compiler;
import org.apache.xpath.compiler.FunctionTable;
import org.apache.xpath.compiler.XPathParser;
@@ -270,6 +272,16 @@ public class XPath implements Serializable, ExpressionOwner
parser = new XPathParser(errorListener, locator);
compiler = new Compiler(errorListener, locator, m_funcTable);
String xpathTwoExprStr = pathExprFunctionSuffix.getXPathTwoStr();
+ if (xpathTwoExprStr.contains(":")) {
+ StylesheetHandler stylesheetHandler = (StylesheetHandler)prefixResolver;
+ Hashtable nsUriTable = stylesheetHandler.getNamespaceUriTable();
+ Enumeration nsUriTableKeys = nsUriTable.keys();
+ while (nsUriTableKeys.hasMoreElements()) {
+ String key = (nsUriTableKeys.nextElement()).toString();
+ String value = (nsUriTable.get(key)).toString();
+ xpathTwoExprStr = xpathTwoExprStr.replace(key, value);
+ }
+ }
parser.initXPath(compiler, xpathTwoExprStr, prefixResolver, false);
Expression expr2 = compiler.compile(0);
@@ -277,9 +289,10 @@ public class XPath implements Serializable, ExpressionOwner
expr = expr1;
- if ((expr instanceof WalkingIterator) && (expr2 instanceof Function)) {
- WalkingIterator walkingIter = (WalkingIterator)expr;
- walkingIter.setFuncExpr((Function)expr2);
+ if ((expr instanceof LocPathIterator) && (expr2 instanceof Function)) {
+ LocPathIterator locPathIter = (LocPathIterator)expr;
+ expr2.exprSetParent((ExpressionNode)locator);
+ locPathIter.setFuncExpr((Function)expr2);
}
}
}
diff --git a/src/org/apache/xpath/axes/LocPathIterator.java b/src/org/apache/xpath/axes/LocPathIterator.java
index e6b99928b..b080e9990 100644
--- a/src/org/apache/xpath/axes/LocPathIterator.java
+++ b/src/org/apache/xpath/axes/LocPathIterator.java
@@ -32,6 +32,7 @@ import org.apache.xpath.ExpressionOwner;
import org.apache.xpath.XPathContext;
import org.apache.xpath.XPathVisitor;
import org.apache.xpath.compiler.Compiler;
+import org.apache.xpath.functions.Function;
import org.apache.xpath.objects.XNodeSet;
import org.apache.xpath.objects.XObject;
import org.apache.xpath.res.XPATHErrorResources;
@@ -52,6 +53,13 @@ public abstract class LocPathIterator extends PredicatedNodeTest
implements Cloneable, DTMIterator, java.io.Serializable, PathComponent
{
static final long serialVersionUID = -4602476357268405754L;
+
+ /**
+ * If there's a function call suffix at an end of XPath expression
+ * similar to /a/b/funcCall(..), we keep a compiled Function
+ * object for funcCall(..) within this class field.
+ */
+ private Function m_func_expr = null;
/**
* Create a LocPathIterator object.
@@ -1031,5 +1039,13 @@ public abstract class LocPathIterator extends PredicatedNodeTest
{
return getLength();
}
+
+ public void setFuncExpr(Function expr) {
+ m_func_expr = expr;
+ }
+
+ public Function getFuncExpr() {
+ return m_func_expr;
+ }
}
diff --git a/src/org/apache/xpath/axes/WalkingIterator.java b/src/org/apache/xpath/axes/WalkingIterator.java
index caebd75cc..c2eaaced1 100644
--- a/src/org/apache/xpath/axes/WalkingIterator.java
+++ b/src/org/apache/xpath/axes/WalkingIterator.java
@@ -28,7 +28,6 @@ import org.apache.xpath.VariableStack;
import org.apache.xpath.XPathVisitor;
import org.apache.xpath.compiler.Compiler;
import org.apache.xpath.compiler.OpMap;
-import org.apache.xpath.functions.Function;
/**
* Location path iterator that uses Walkers.
@@ -37,13 +36,6 @@ public class WalkingIterator extends LocPathIterator implements ExpressionOwner
{
static final long serialVersionUID = 9110225941815665906L;
- /**
- * If there's a function call suffix at an end of XPath expression
- * similar to /a/b/funcCall(..), we keep a compiled Function
- * object for funcCall(..) within this class field.
- */
- private Function m_func_expr = null;
-
/**
* Create a WalkingIterator iterator, including creation
* of step walkers from the opcode list, and call back
@@ -366,12 +358,4 @@ public class WalkingIterator extends LocPathIterator implements ExpressionOwner
return true;
}
- public void setFuncExpr(Function expr) {
- m_func_expr = expr;
- }
-
- public Function getFuncExpr() {
- return m_func_expr;
- }
-
}
diff --git a/src/org/apache/xpath/compiler/XPathParser.java b/src/org/apache/xpath/compiler/XPathParser.java
index b7745844b..00e5480bf 100644
--- a/src/org/apache/xpath/compiler/XPathParser.java
+++ b/src/org/apache/xpath/compiler/XPathParser.java
@@ -1933,11 +1933,11 @@ public class XPathParser
bindingXPathExprStrPartsList.size() - 1);
}
- String varBindingXpathStr = getXPathStrFromComponentParts(bindingXPathExprStrPartsList);
+ String varBindingXPathStr = getXPathStrFromComponentParts(bindingXPathExprStrPartsList);
LetExprVarBinding letExprVarBinding = new LetExprVarBinding();
letExprVarBinding.setVarName(bindingVarName);
- letExprVarBinding.setXpathExprStr(varBindingXpathStr);
+ letExprVarBinding.setXPathExprStr(varBindingXPathStr);
letExprVarBindingList.add(letExprVarBinding);
@@ -4033,7 +4033,6 @@ public class XPathParser
boolean funcMatchFound = false;
- // The next blocks guarantee that a FROM_XXX will be added.
if (lookahead("::", 1))
{
axesType = AxisName();
@@ -4100,6 +4099,23 @@ public class XPathParser
if (tokenObj instanceof XString) {
m_token = "'" + ((XString)tokenObj).str() + "'";
}
+ else if (tokenObj instanceof XNumber) {
+ XNumber xNumber = (XNumber)tokenObj;
+ String strVal = null;
+ if (xNumber.getXsDecimal() != null) {
+ strVal = (xNumber.getXsDecimal()).stringValue();
+ }
+ else if (xNumber.getXsDouble() != null) {
+ strVal = (xNumber.getXsDouble()).stringValue();
+ }
+ else if (xNumber.getXsInteger() != null) {
+ strVal = (xNumber.getXsInteger()).stringValue();
+ }
+ else {
+ strVal = xNumber.str();
+ }
+ m_token = strVal;
+ }
else {
m_token = (String)tokenObj;
}
diff --git a/src/org/apache/xpath/composite/LetExprVarBinding.java b/src/org/apache/xpath/composite/LetExprVarBinding.java
index 0e555b33f..59953ec35 100644
--- a/src/org/apache/xpath/composite/LetExprVarBinding.java
+++ b/src/org/apache/xpath/composite/LetExprVarBinding.java
@@ -16,7 +16,7 @@
*/
package org.apache.xpath.composite;
-/*
+/**
* An object of this class, is used to store information about
* XPath 3.1 "let" expression's single variable binding (i.e,
* run-time information details related to the grammar fragment
@@ -29,24 +29,24 @@ package org.apache.xpath.composite;
*/
public class LetExprVarBinding {
- private String fVarName = null;
+ private String m_varName = null;
- private String fXpathExprStr = null;
+ private String m_xpathExprStr = null;
public String getVarName() {
- return fVarName;
+ return m_varName;
}
public void setVarName(String varName) {
- this.fVarName = varName;
+ this.m_varName = varName;
}
- public String getXpathExprStr() {
- return fXpathExprStr;
+ public String getXPathExprStr() {
+ return m_xpathExprStr;
}
- public void setXpathExprStr(String xpathExprStr) {
- this.fXpathExprStr = xpathExprStr;
+ public void setXPathExprStr(String xpathExprStr) {
+ this.m_xpathExprStr = xpathExprStr;
}
}
diff --git a/src/org/apache/xpath/composite/XPathLetExpr.java b/src/org/apache/xpath/composite/XPathLetExpr.java
index 25f4681ea..24efd12b2 100644
--- a/src/org/apache/xpath/composite/XPathLetExpr.java
+++ b/src/org/apache/xpath/composite/XPathLetExpr.java
@@ -37,7 +37,7 @@ import org.apache.xpath.XPathVisitor;
import org.apache.xpath.objects.ResultSequence;
import org.apache.xpath.objects.XObject;
-/*
+/**
* An implementation of XPath 3.1 'let' expression.
*
* Ref : https://www.w3.org/TR/xpath-31/#id-let-expressions
@@ -50,10 +50,10 @@ public class XPathLetExpr extends Expression {
private static final long serialVersionUID = 3063682088023616108L;
- private List<LetExprVarBinding> m_LetExprVarBindingList =
+ private List<LetExprVarBinding> m_letExprVarBindingList =
new ArrayList<LetExprVarBinding>();
- private String m_ReturnExprXPathStr = null;
+ private String m_returnExprXPathStr = null;
// The following two fields of this class, are used during
// XPath.fixupVariables(..) action as performed within object of
@@ -83,23 +83,23 @@ public class XPathLetExpr extends Expression {
Map<QName, XObject> letExprVarBindingMap = new HashMap<QName, XObject>();
- for (int idx = 0; idx < m_LetExprVarBindingList.size(); idx++) {
- LetExprVarBinding letExprVarBinding = m_LetExprVarBindingList.get(idx);
+ for (int idx = 0; idx < m_letExprVarBindingList.size(); idx++) {
+ LetExprVarBinding letExprVarBinding = m_letExprVarBindingList.get(idx);
String varName = letExprVarBinding.getVarName();
- String fXpathExprStr = letExprVarBinding.getXpathExprStr();
+ String varResultXPathExprStr = letExprVarBinding.getXPathExprStr();
if (prefixTable != null) {
- fXpathExprStr = XslTransformEvaluationHelper.replaceNsUrisWithPrefixesOnXPathStr(
- fXpathExprStr, prefixTable);
+ varResultXPathExprStr = XslTransformEvaluationHelper.replaceNsUrisWithPrefixesOnXPathStr(
+ varResultXPathExprStr, prefixTable);
}
- XPath letExprVarBindingXpath = new XPath(fXpathExprStr, srcLocator, xctxt.getNamespaceContext(),
+ XPath letExprVarBindingXPath = new XPath(varResultXPathExprStr, srcLocator, xctxt.getNamespaceContext(),
XPath.SELECT, null);
if (m_vars != null) {
- letExprVarBindingXpath.fixupVariables(m_vars, m_globals_size);
+ letExprVarBindingXPath.fixupVariables(m_vars, m_globals_size);
}
- XObject varBindingEvalResult = letExprVarBindingXpath.execute(xctxt, contextNode,
+ XObject varBindingEvalResult = letExprVarBindingXPath.execute(xctxt, contextNode,
xctxt.getNamespaceContext());
m_xpathVarList.add(new QName(varName));
@@ -111,11 +111,11 @@ public class XPathLetExpr extends Expression {
xpathVarMap.putAll(letExprVarBindingMap);
if (prefixTable != null) {
- m_ReturnExprXPathStr = XslTransformEvaluationHelper.replaceNsUrisWithPrefixesOnXPathStr(
- m_ReturnExprXPathStr, prefixTable);
+ m_returnExprXPathStr = XslTransformEvaluationHelper.replaceNsUrisWithPrefixesOnXPathStr(
+ m_returnExprXPathStr, prefixTable);
}
- XPath returnExprXpath = new XPath(m_ReturnExprXPathStr, srcLocator, xctxt.getNamespaceContext(),
+ XPath returnExprXpath = new XPath(m_returnExprXPathStr, srcLocator, xctxt.getNamespaceContext(),
XPath.SELECT, null);
if (m_vars != null) {
@@ -144,19 +144,19 @@ public class XPathLetExpr extends Expression {
}
public List<LetExprVarBinding> getLetExprVarBindingList() {
- return m_LetExprVarBindingList;
+ return m_letExprVarBindingList;
}
- public void setLetExprVarBindingList(List<LetExprVarBinding> fLetExprVarBindingList) {
- this.m_LetExprVarBindingList = fLetExprVarBindingList;
+ public void setLetExprVarBindingList(List<LetExprVarBinding> letExprVarBindingList) {
+ this.m_letExprVarBindingList = letExprVarBindingList;
}
public String getReturnExprXPathStr() {
- return m_ReturnExprXPathStr;
+ return m_returnExprXPathStr;
}
- public void setReturnExprXPathStr(String fReturnExprXPathStr) {
- this.m_ReturnExprXPathStr = fReturnExprXPathStr;
+ public void setReturnExprXPathStr(String returnExprXPathStr) {
+ this.m_returnExprXPathStr = returnExprXPathStr;
}
}
diff --git a/src/org/apache/xpath/functions/FuncLocalName.java b/src/org/apache/xpath/functions/FuncLocalName.java
index 5273836e4..1ab4fff67 100644
--- a/src/org/apache/xpath/functions/FuncLocalName.java
+++ b/src/org/apache/xpath/functions/FuncLocalName.java
@@ -17,10 +17,13 @@
*/
package org.apache.xpath.functions;
+import javax.xml.transform.SourceLocator;
+
import org.apache.xml.dtm.DTM;
import org.apache.xml.dtm.DTMIterator;
import org.apache.xml.dtm.DTMManager;
import org.apache.xpath.XPathContext;
+import org.apache.xpath.axes.SelfIteratorNoPredicate;
import org.apache.xpath.objects.XNodeSet;
import org.apache.xpath.objects.XObject;
import org.w3c.dom.Node;
@@ -45,24 +48,58 @@ public class FuncLocalName extends FunctionDef1Arg {
*
* @throws javax.xml.transform.TransformerException
*/
- public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException {
+ public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException {
+
+ XSString result = null;
+
+ SourceLocator srcLocator = xctxt.getSAXLocator();
+
int nodeHandle = DTM.NULL;
if (m_arg0 == null) {
nodeHandle = xctxt.getCurrentNode();
}
- else {
+ else if (m_arg0 instanceof SelfIteratorNoPredicate) {
+ XObject contextItem = xctxt.getXPath3ContextItem();
+ if ((contextItem != null) && (contextItem instanceof XNodeSet)) {
+ nodeHandle = getNodeHandle((XNodeSet)contextItem);
+ }
+ else {
+ XObject xObject = m_arg0.execute(xctxt);
+ if (xObject instanceof XNodeSet) {
+ nodeHandle = getNodeHandle((XNodeSet)xObject);
+ }
+ }
+ }
+ else {
XObject xObject = m_arg0.execute(xctxt);
if (xObject instanceof XNodeSet) {
- XNodeSet nodeSet = (XNodeSet)xObject;
- DTMIterator dtmIter = nodeSet.iterRaw();
- nodeHandle = dtmIter.nextNode();
+ nodeHandle = getNodeHandle((XNodeSet)xObject);
}
}
+
+ if (nodeHandle == DTM.NULL) {
+ throw new javax.xml.transform.TransformerException("XPTY0004: The 1st argument of XPath function "
+ + "fn:local-name is not a node, or there's no context node.", srcLocator);
+ }
String localNameStrVal = getLocalName(nodeHandle, xctxt);
+
+ result = new XSString(localNameStrVal);
- return new XSString(localNameStrVal);
+ return result;
+ }
+
+ /**
+ * Get dtm node handle of a node.
+ */
+ private int getNodeHandle(XNodeSet nodeSet) {
+ int nodeHandle;
+
+ DTMIterator dtmIter = nodeSet.iterRaw();
+ nodeHandle = dtmIter.nextNode();
+
+ return nodeHandle;
}
/**
diff --git a/src/org/apache/xpath/functions/FuncName.java b/src/org/apache/xpath/functions/FuncName.java
index 994566884..1ff38ab29 100644
--- a/src/org/apache/xpath/functions/FuncName.java
+++ b/src/org/apache/xpath/functions/FuncName.java
@@ -23,6 +23,7 @@ import org.apache.xml.dtm.DTM;
import org.apache.xml.dtm.DTMIterator;
import org.apache.xpath.Expression;
import org.apache.xpath.XPathContext;
+import org.apache.xpath.axes.SelfIteratorNoPredicate;
import org.apache.xpath.objects.XNodeSet;
import org.apache.xpath.objects.XObject;
import org.w3c.dom.Node;
@@ -52,36 +53,77 @@ public class FuncName extends FunctionMultiArgs {
public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
{
- XObject result = null;
+ XSString result = null;
SourceLocator srcLocator = xctxt.getSAXLocator();
Expression arg0 = getArg0();
String nodeNameStr = null;
+ int nodeHandle = DTM.NULL;
+
if (arg0 == null) {
- int contextNode = xctxt.getCurrentNode();
- DTM dtm = xctxt.getDTM(contextNode);
- Node node = dtm.getNode(contextNode);
- nodeNameStr = node.getNodeName();
+ nodeHandle = xctxt.getCurrentNode();
+ nodeNameStr = getNodeNameStrFromNodeHandle(nodeHandle, xctxt);
+ }
+ else if (arg0 instanceof SelfIteratorNoPredicate) {
+ XObject contextItem = xctxt.getXPath3ContextItem();
+ if ((contextItem != null) && (contextItem instanceof XNodeSet)) {
+ nodeHandle = getNodeHandle((XNodeSet)contextItem);
+ nodeNameStr = getNodeNameStrFromNodeHandle(nodeHandle, xctxt);
+ }
+ else {
+ XObject xObject = m_arg0.execute(xctxt);
+ if (xObject instanceof XNodeSet) {
+ nodeHandle = getNodeHandle((XNodeSet)xObject);
+ nodeNameStr = getNodeNameStrFromNodeHandle(nodeHandle, xctxt);
+ }
+ }
}
else {
XObject nodeArg = arg0.execute(xctxt);
+
if (nodeArg instanceof XNodeSet) {
XNodeSet nodeSet = (XNodeSet)nodeArg;
DTMIterator dtmIter = nodeSet.iterRaw();
- int nodeHandle = dtmIter.nextNode();
- DTM dtm = xctxt.getDTM(nodeHandle);
- Node node = dtm.getNode(nodeHandle);
- nodeNameStr = node.getNodeName();
- }
- else {
- throw new javax.xml.transform.TransformerException("XPTY0004: The 1st argument of function fn:name is not a node.", srcLocator);
+ nodeHandle = dtmIter.nextNode();
+ nodeNameStr = getNodeNameStrFromNodeHandle(nodeHandle, xctxt);
}
}
+ if (nodeHandle == DTM.NULL) {
+ throw new javax.xml.transform.TransformerException("XPTY0004: The 1st argument of XPath function "
+ + "fn:name is not a node, or there's no context node.", srcLocator);
+ }
+
result = new XSString(nodeNameStr);
return result;
}
+
+ /**
+ * Get dtm node handle of a node.
+ */
+ private int getNodeHandle(XNodeSet nodeSet) {
+ int nodeHandle;
+
+ DTMIterator dtmIter = nodeSet.iterRaw();
+ nodeHandle = dtmIter.nextNode();
+
+ return nodeHandle;
+ }
+
+ /**
+ * Get node-name string value of xpath node.
+ */
+ private String getNodeNameStrFromNodeHandle(int nodeHandle, XPathContext xctxt) {
+ String nodeNameStr = null;
+
+ DTM dtm = xctxt.getDTM(nodeHandle);
+ Node node = dtm.getNode(nodeHandle);
+ nodeNameStr = node.getNodeName();
+
+ return nodeNameStr;
+ }
+
}
diff --git a/src/org/apache/xpath/functions/FunctionDef1Arg.java b/src/org/apache/xpath/functions/FunctionDef1Arg.java
index 58b721eee..20f0fdcc4 100644
--- a/src/org/apache/xpath/functions/FunctionDef1Arg.java
+++ b/src/org/apache/xpath/functions/FunctionDef1Arg.java
@@ -145,11 +145,20 @@ public class FunctionDef1Arg extends FunctionOneArg
DTM dtm = xctxt.getDTM(currentNode);
XMLString str = dtm.getStringValue(currentNode);
return str.toDouble();
- }
-
+ }
}
- else
- return m_arg0.execute(xctxt).num();
+ else if (m_arg0 instanceof SelfIteratorNoPredicate) {
+ XObject contextItem = xctxt.getXPath3ContextItem();
+ if (contextItem != null) {
+ String argStrVal = XslTransformEvaluationHelper.getStrVal(contextItem);
+ return (Double.valueOf(argStrVal)).doubleValue();
+ }
+ else {
+ return m_arg0.execute(xctxt).num();
+ }
+ }
+ else
+ return m_arg0.execute(xctxt).num();
}
/**
diff --git a/src/org/apache/xpath/functions/XSLFunctionService.java b/src/org/apache/xpath/functions/XSLFunctionService.java
index 29af7c64a..f5599a5b6 100644
--- a/src/org/apache/xpath/functions/XSLFunctionService.java
+++ b/src/org/apache/xpath/functions/XSLFunctionService.java
@@ -17,6 +17,9 @@
package org.apache.xpath.functions;
import java.io.StringReader;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
@@ -40,8 +43,10 @@ import org.apache.xerces.impl.xs.XSLoaderImpl;
import org.apache.xerces.xs.XSModel;
import org.apache.xerces.xs.XSTypeDefinition;
import org.apache.xml.utils.QName;
+import org.apache.xpath.Expression;
import org.apache.xpath.ExpressionNode;
import org.apache.xpath.XPathContext;
+import org.apache.xpath.axes.SelfIteratorNoPredicate;
import org.apache.xpath.compiler.Keywords;
import org.apache.xpath.objects.ResultSequence;
import org.apache.xpath.objects.XObject;
@@ -85,9 +90,8 @@ import xml.xpath31.processor.types.XSToken;
import xml.xpath31.processor.types.XSYearMonthDuration;
/**
- * An object of this class supports evaluation of an XPath
- * constructor function call, and an XSL stylesheet function
- * call.
+ * An object of this class supports evaluation of XPath
+ * constructor function and XSL stylesheet function calls.
*
* @author Mukul Gandhi <mu...@apache.org>
*
@@ -151,354 +155,226 @@ public class XSLFunctionService {
stylesheetRoot = (StylesheetRoot)stylesheetRootNode;
- if (transformerImpl == null) {
- transformerImpl = stylesheetRoot.getTransformerImpl();
- }
+ if (stylesheetRoot != null) {
+ if (transformerImpl == null) {
+ transformerImpl = stylesheetRoot.getTransformerImpl();
+ }
- TemplateList templateList = stylesheetRoot.getTemplateListComposed();
+ TemplateList templateList = stylesheetRoot.getTemplateListComposed();
- ElemTemplate elemTemplate = templateList.getTemplate(new QName(funcNamespace, funcName));
+ ElemTemplate elemTemplate = templateList.getTemplate(new QName(funcNamespace, funcName));
- if ((elemTemplate != null) && (elemTemplate instanceof ElemFunction)) {
- // Evaluate XSL stylesheet function call
- ResultSequence argSequence = new ResultSequence();
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- argSequence.add(argVal);
- }
+ if ((elemTemplate != null) && (elemTemplate instanceof ElemFunction)) {
+ // Evaluate XSL stylesheet function call
+ ResultSequence argSequence = new ResultSequence();
+ for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+ XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
+ argSequence.add(argVal);
+ }
- evalResult = ((ElemFunction)elemTemplate).evaluateXslFunction(transformerImpl, argSequence);
- }
- else if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(funcNamespace)) {
+ evalResult = ((ElemFunction)elemTemplate).evaluateXslFunction(transformerImpl, argSequence);
+
+ return evalResult;
+ }
+ }
+
+ if (XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(funcNamespace)) {
// Evaluate XPath constructor function call, for schema types
// in XML Schema namespace.
+
ResultSequence argSequence = new ResultSequence();
ResultSequence evalResultSequence = null;
- switch (funcName) {
- case Keywords.XS_STRING :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- argSequence.add(new XSString(XslTransformEvaluationHelper.getStrVal(argVal)));
- }
-
- evalResultSequence = (new XSString()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
-
- break;
- case Keywords.XS_NORMALIZED_STRING :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- argSequence.add(new XSNormalizedString(XslTransformEvaluationHelper.getStrVal(argVal)));
- }
-
- evalResultSequence = (new XSNormalizedString()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
-
- break;
- case Keywords.XS_TOKEN :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- argSequence.add(new XSToken(XslTransformEvaluationHelper.getStrVal(argVal)));
- }
-
- evalResultSequence = (new XSToken()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
-
- break;
- case Keywords.XS_DECIMAL :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- argSequence.add(new XSDecimal(XslTransformEvaluationHelper.getStrVal(argVal)));
- }
-
- evalResultSequence = (new XSDecimal()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
-
- break;
- case Keywords.XS_FLOAT :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- argSequence.add(new XSFloat(XslTransformEvaluationHelper.getStrVal(argVal)));
- }
-
- evalResultSequence = (new XSFloat()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
-
- break;
- case Keywords.XS_DOUBLE :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- argSequence.add(new XSDouble(XslTransformEvaluationHelper.getStrVal(argVal)));
- }
-
- evalResultSequence = (new XSDouble()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
-
- break;
- case Keywords.XS_INTEGER :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- argSequence.add(new XSInteger(XslTransformEvaluationHelper.getStrVal(argVal)));
- }
-
- evalResultSequence = (new XSInteger()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
-
- break;
- case Keywords.XS_NON_POSITIVE_INTEGER :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- argSequence.add(new XSNonPositiveInteger(XslTransformEvaluationHelper.getStrVal(argVal)));
- }
-
- evalResultSequence = (new XSNonPositiveInteger()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
-
- break;
- case Keywords.XS_NEGATIVE_INTEGER :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- argSequence.add(new XSNegativeInteger(XslTransformEvaluationHelper.getStrVal(argVal)));
- }
-
- evalResultSequence = (new XSNegativeInteger()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
-
- break;
- case Keywords.XS_NON_NEGATIVE_INTEGER :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- argSequence.add(new XSNonNegativeInteger(XslTransformEvaluationHelper.getStrVal(argVal)));
- }
-
- evalResultSequence = (new XSNonNegativeInteger()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
-
- break;
- case Keywords.XS_POSITIVE_INTEGER :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- argSequence.add(new XSPositiveInteger(XslTransformEvaluationHelper.getStrVal(argVal)));
- }
-
- evalResultSequence = (new XSPositiveInteger()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
-
- break;
- case Keywords.XS_LONG :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- argSequence.add(new XSLong(XslTransformEvaluationHelper.getStrVal(argVal)));
- }
-
- evalResultSequence = (new XSLong()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
-
- break;
- case Keywords.XS_INT :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- argSequence.add(new XSInt(XslTransformEvaluationHelper.getStrVal(argVal)));
- }
-
- evalResultSequence = (new XSInt()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
-
- break;
- case Keywords.XS_SHORT :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- argSequence.add(new XSShort(XslTransformEvaluationHelper.getStrVal(argVal)));
- }
-
- evalResultSequence = (new XSShort()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
-
- break;
- case Keywords.XS_BYTE :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- argSequence.add(new XSByte(XslTransformEvaluationHelper.getStrVal(argVal)));
- }
-
- evalResultSequence = (new XSByte()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
-
- break;
- case Keywords.XS_UNSIGNED_LONG :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- argSequence.add(new XSUnsignedLong(XslTransformEvaluationHelper.getStrVal(argVal)));
- }
-
- evalResultSequence = (new XSUnsignedLong()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
-
- break;
- case Keywords.XS_UNSIGNED_INT :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- argSequence.add(new XSUnsignedInt(XslTransformEvaluationHelper.getStrVal(argVal)));
- }
-
- evalResultSequence = (new XSUnsignedInt()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
-
- break;
- case Keywords.XS_UNSIGNED_SHORT :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- argSequence.add(new XSUnsignedShort(XslTransformEvaluationHelper.getStrVal(argVal)));
- }
-
- evalResultSequence = (new XSUnsignedShort()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
-
- break;
- case Keywords.XS_UNSIGNED_BYTE :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- argSequence.add(new XSUnsignedByte(XslTransformEvaluationHelper.getStrVal(argVal)));
- }
-
- evalResultSequence = (new XSUnsignedByte()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
-
- break;
- case Keywords.FUNC_BOOLEAN_STRING :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- String argStrVal = XslTransformEvaluationHelper.getStrVal(argVal);
- Boolean boolVal = Boolean.valueOf(("0".equals(argStrVal) || "false".equals(argStrVal)) ?
- "false" : "true");
- argSequence.add(new XSBoolean(boolVal));
- }
-
- evalResultSequence = (new XSBoolean()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
-
- break;
- case Keywords.XS_DATE :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- argSequence.add(XSDate.parseDate(XslTransformEvaluationHelper.getStrVal(argVal)));
- }
-
- evalResultSequence = (new XSDate()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
-
- break;
- case Keywords.XS_DATETIME :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- argSequence.add(XSDateTime.parseDateTime(XslTransformEvaluationHelper.getStrVal(argVal)));
- }
-
- evalResultSequence = (new XSDateTime()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
-
- break;
- case Keywords.XS_DURATION :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- String strVal = XslTransformEvaluationHelper.getStrVal(argVal);
- XSDuration xsDuration = XSDuration.parseDuration(strVal);
- if (xsDuration != null) {
- argSequence.add(xsDuration);
- evalResultSequence = (new XSDuration()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
- }
- else {
- throw new TransformerException("FORG0001 : An incorrectly formatted xs:duration value '" +
- strVal + "' is present in the input.", srcLocator);
- }
- }
-
- break;
- case Keywords.XS_YEAR_MONTH_DURATION :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- String strVal = XslTransformEvaluationHelper.getStrVal(argVal);
- XSDuration xsDuration = XSYearMonthDuration.parseYearMonthDuration(strVal);
- if (xsDuration != null) {
- argSequence.add(xsDuration);
- evalResultSequence = (new XSYearMonthDuration()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
- }
- else {
- throw new TransformerException("FORG0001 : An incorrectly formatted xs:yearMonthDuration value '" +
- strVal + "' is present in the input.", srcLocator);
- }
- }
-
- break;
- case Keywords.XS_DAY_TIME_DURATION :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- String strVal = XslTransformEvaluationHelper.getStrVal(argVal);
- XSDuration xsDuration = XSDayTimeDuration.parseDayTimeDuration(strVal);
- if (xsDuration != null) {
- argSequence.add(xsDuration);
- evalResultSequence = (new XSDayTimeDuration()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
- }
- else {
- throw new TransformerException("FORG0001 : An incorrectly formatted xs:dayTimeDuration value '" +
- strVal + "' is present in the input.", srcLocator);
- }
- }
-
- break;
- case Keywords.XS_TIME :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- String strVal = XslTransformEvaluationHelper.getStrVal(argVal);
- XSTime xsTime = XSTime.parseTime(strVal);
- if (xsTime != null) {
- argSequence.add(xsTime);
- evalResultSequence = (new XSTime()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
- }
- else {
- throw new TransformerException("FORG0001 : An incorrectly formatted xs:time value '" +
- strVal + "' is present in the input.", srcLocator);
- }
- }
-
- break;
- case Keywords.XS_ANY_URI :
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- argSequence.add(new XSAnyURI(XslTransformEvaluationHelper.getStrVal(argVal)));
- }
-
- evalResultSequence = (new XSAnyURI()).constructor(argSequence);
- evalResult = evalResultSequence.item(0);
-
- break;
- case Keywords.XS_QNAME :
- XSQName xsQName = new XSQName();
- for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
- XObject argVal = (funcObj.getArg(idx)).execute(xctxt);
- String argStrVal = XslTransformEvaluationHelper.getStrVal(argVal);
- if (idx == 0) {
- xsQName.setPrefix(argStrVal);
- }
- else if (idx == 1) {
- xsQName.setLocalPart(argStrVal);
- }
- else {
- xsQName.setNamespaceUri(argStrVal);
- }
- }
-
- evalResult = xsQName;
-
- break;
- default:
- // no op
- }
+ try {
+ switch (funcName) {
+ case Keywords.XS_STRING :
+ evalResult = evaluateXPathBuiltInConstructionFunctionCall(funcObj, XSString.class, xctxt);
+ break;
+ case Keywords.XS_NORMALIZED_STRING :
+ evalResult = evaluateXPathBuiltInConstructionFunctionCall(funcObj, XSNormalizedString.class, xctxt);
+ break;
+ case Keywords.XS_TOKEN :
+ evalResult = evaluateXPathBuiltInConstructionFunctionCall(funcObj, XSToken.class, xctxt);
+ break;
+ case Keywords.XS_DECIMAL :
+ evalResult = evaluateXPathBuiltInConstructionFunctionCall(funcObj, XSDecimal.class, xctxt);
+ break;
+ case Keywords.XS_FLOAT :
+ evalResult = evaluateXPathBuiltInConstructionFunctionCall(funcObj, XSFloat.class, xctxt);
+ break;
+ case Keywords.XS_DOUBLE :
+ evalResult = evaluateXPathBuiltInConstructionFunctionCall(funcObj, XSDouble.class, xctxt);
+ break;
+ case Keywords.XS_INTEGER :
+ evalResult = evaluateXPathBuiltInConstructionFunctionCall(funcObj, XSInteger.class, xctxt);
+ break;
+ case Keywords.XS_NON_POSITIVE_INTEGER :
+ evalResult = evaluateXPathBuiltInConstructionFunctionCall(funcObj, XSNonPositiveInteger.class, xctxt);
+ break;
+ case Keywords.XS_NEGATIVE_INTEGER :
+ evalResult = evaluateXPathBuiltInConstructionFunctionCall(funcObj, XSNegativeInteger.class, xctxt);
+ break;
+ case Keywords.XS_NON_NEGATIVE_INTEGER :
+ evalResult = evaluateXPathBuiltInConstructionFunctionCall(funcObj, XSNonNegativeInteger.class, xctxt);
+ break;
+ case Keywords.XS_POSITIVE_INTEGER :
+ evalResult = evaluateXPathBuiltInConstructionFunctionCall(funcObj, XSPositiveInteger.class, xctxt);
+ break;
+ case Keywords.XS_LONG :
+ evalResult = evaluateXPathBuiltInConstructionFunctionCall(funcObj, XSLong.class, xctxt);
+ break;
+ case Keywords.XS_INT :
+ evalResult = evaluateXPathBuiltInConstructionFunctionCall(funcObj, XSInt.class, xctxt);
+ break;
+ case Keywords.XS_SHORT :
+ evalResult = evaluateXPathBuiltInConstructionFunctionCall(funcObj, XSShort.class, xctxt);
+ break;
+ case Keywords.XS_BYTE :
+ evalResult = evaluateXPathBuiltInConstructionFunctionCall(funcObj, XSByte.class, xctxt);
+ break;
+ case Keywords.XS_UNSIGNED_LONG :
+ evalResult = evaluateXPathBuiltInConstructionFunctionCall(funcObj, XSUnsignedLong.class, xctxt);
+ break;
+ case Keywords.XS_UNSIGNED_INT :
+ evalResult = evaluateXPathBuiltInConstructionFunctionCall(funcObj, XSUnsignedInt.class, xctxt);
+ break;
+ case Keywords.XS_UNSIGNED_SHORT :
+ evalResult = evaluateXPathBuiltInConstructionFunctionCall(funcObj, XSUnsignedShort.class, xctxt);
+ break;
+ case Keywords.XS_UNSIGNED_BYTE :
+ evalResult = evaluateXPathBuiltInConstructionFunctionCall(funcObj, XSUnsignedByte.class, xctxt);
+ break;
+ case Keywords.FUNC_BOOLEAN_STRING :
+ for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+ Expression funcArg = funcObj.getArg(idx);
+ String argStr = getXPathBuiltInConstructorFunctionArgStr(funcArg, xctxt);
+ Boolean boolVal = Boolean.valueOf(("0".equals(argStr) || "false".equals(argStr)) ?
+ "false" : "true");
+ argSequence.add(new XSBoolean(boolVal));
+ }
+ evalResultSequence = (new XSBoolean()).constructor(argSequence);
+ evalResult = evalResultSequence.item(0);
+
+ break;
+ case Keywords.XS_DATE :
+ for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+ Expression funcArg = funcObj.getArg(idx);
+ String argStr = getXPathBuiltInConstructorFunctionArgStr(funcArg, xctxt);
+ argSequence.add(XSDate.parseDate(argStr));
+ }
+ evalResultSequence = (new XSDate()).constructor(argSequence);
+ evalResult = evalResultSequence.item(0);
+
+ break;
+ case Keywords.XS_DATETIME :
+ for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+ Expression funcArg = funcObj.getArg(idx);
+ String argStr = getXPathBuiltInConstructorFunctionArgStr(funcArg, xctxt);
+ argSequence.add(XSDateTime.parseDateTime(argStr));
+ }
+ evalResultSequence = (new XSDateTime()).constructor(argSequence);
+ evalResult = evalResultSequence.item(0);
+
+ break;
+ case Keywords.XS_DURATION :
+ for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+ Expression funcArg = funcObj.getArg(idx);
+ String argStr = getXPathBuiltInConstructorFunctionArgStr(funcArg, xctxt);
+ XSDuration xsDuration = XSDuration.parseDuration(argStr);
+ if (xsDuration != null) {
+ argSequence.add(xsDuration);
+ evalResultSequence = (new XSDuration()).constructor(argSequence);
+ evalResult = evalResultSequence.item(0);
+ }
+ else {
+ throw new TransformerException("FORG0001 : An incorrectly formatted xs:duration value '" +
+ argStr + "' is present in the input.", srcLocator);
+ }
+ }
+
+ break;
+ case Keywords.XS_YEAR_MONTH_DURATION :
+ for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+ Expression funcArg = funcObj.getArg(idx);
+ String argStr = getXPathBuiltInConstructorFunctionArgStr(funcArg, xctxt);
+ XSDuration xsDuration = XSYearMonthDuration.parseYearMonthDuration(argStr);
+ if (xsDuration != null) {
+ argSequence.add(xsDuration);
+ evalResultSequence = (new XSYearMonthDuration()).constructor(argSequence);
+ evalResult = evalResultSequence.item(0);
+ }
+ else {
+ throw new TransformerException("FORG0001 : An incorrectly formatted xs:yearMonthDuration value '" +
+ argStr + "' is present in the input.", srcLocator);
+ }
+ }
+
+ break;
+ case Keywords.XS_DAY_TIME_DURATION :
+ for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+ Expression funcArg = funcObj.getArg(idx);
+ String argStr = getXPathBuiltInConstructorFunctionArgStr(funcArg, xctxt);
+ XSDuration xsDuration = XSDayTimeDuration.parseDayTimeDuration(argStr);
+ if (xsDuration != null) {
+ argSequence.add(xsDuration);
+ evalResultSequence = (new XSDayTimeDuration()).constructor(argSequence);
+ evalResult = evalResultSequence.item(0);
+ }
+ else {
+ throw new TransformerException("FORG0001 : An incorrectly formatted xs:dayTimeDuration value '" +
+ argStr + "' is present in the input.", srcLocator);
+ }
+ }
+
+ break;
+ case Keywords.XS_TIME :
+ for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+ Expression funcArg = funcObj.getArg(idx);
+ String argStr = getXPathBuiltInConstructorFunctionArgStr(funcArg, xctxt);
+ XSTime xsTime = XSTime.parseTime(argStr);
+ if (xsTime != null) {
+ argSequence.add(xsTime);
+ evalResultSequence = (new XSTime()).constructor(argSequence);
+ evalResult = evalResultSequence.item(0);
+ }
+ else {
+ throw new TransformerException("FORG0001 : An incorrectly formatted xs:time value '" +
+ argStr + "' is present in the input.", srcLocator);
+ }
+ }
+
+ break;
+ case Keywords.XS_ANY_URI :
+ evalResult = evaluateXPathBuiltInConstructionFunctionCall(funcObj, XSAnyURI.class, xctxt);
+ break;
+ case Keywords.XS_QNAME :
+ XSQName xsQName = new XSQName();
+ for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+ Expression funcArg = funcObj.getArg(idx);
+ String argStr = getXPathBuiltInConstructorFunctionArgStr(funcArg, xctxt);
+ if (idx == 0) {
+ xsQName.setPrefix(argStr);
+ }
+ else if (idx == 1) {
+ xsQName.setLocalPart(argStr);
+ }
+ else {
+ xsQName.setNamespaceUri(argStr);
+ }
+ }
+
+ evalResult = xsQName;
+
+ break;
+ default:
+ // NO OP
+ }
+ }
+ catch (Exception ex) {
+ throw new TransformerException("FODC0005 : A dynamic error has occured, evaluating XPath built-in "
+ + "constructor function call. " +
+ ex.getMessage() + ".", srcLocator);
+ }
}
else {
// We check and evaluate below, XPath constructor function calls to
@@ -644,4 +520,54 @@ public class XSLFunctionService {
return evalResult;
}
+ /**
+ * Evaluate the XPath built-in constructor function call.
+ */
+ private XObject evaluateXPathBuiltInConstructionFunctionCall(XSLConstructorStylesheetOrExtensionFunction funcObj,
+ Class dataType, XPathContext xctxt) throws TransformerException,
+ InstantiationException, IllegalAccessException,
+ NoSuchMethodException, SecurityException,
+ IllegalArgumentException, InvocationTargetException {
+ XObject evalResult = null;
+
+ ResultSequence evalResultSequence = null;
+ ResultSequence argSequence = new ResultSequence();
+
+ for (int idx = 0; idx < funcObj.getArgCount(); idx++) {
+ Expression funcArg = funcObj.getArg(idx);
+ String argStr = getXPathBuiltInConstructorFunctionArgStr(funcArg, xctxt);
+ Constructor cons = dataType.getConstructor(new Class[] {String.class});
+ Object obj = cons.newInstance(new String[] {argStr});
+ argSequence.add((XObject)obj);
+ }
+
+ Object obj = dataType.newInstance();
+
+ Method method = dataType.getMethod("constructor", new Class[] {ResultSequence.class});
+ evalResultSequence = (ResultSequence)(method.invoke(obj, new Object[] {argSequence}));
+
+ evalResult = evalResultSequence.item(0);
+
+ return evalResult;
+ }
+
+ /**
+ * Get the effective value of XPath built-in constructor function call's argument.
+ */
+ private String getXPathBuiltInConstructorFunctionArgStr(Expression funcArg, XPathContext xctxt)
+ throws TransformerException {
+ String argStr = null;
+
+ if (funcArg instanceof SelfIteratorNoPredicate) {
+ XObject contextItem = xctxt.getXPath3ContextItem();
+ argStr = XslTransformEvaluationHelper.getStrVal(contextItem);
+ }
+ else {
+ XObject argVal = funcArg.execute(xctxt);
+ argStr = XslTransformEvaluationHelper.getStrVal(argVal);
+ }
+
+ return argStr;
+ }
+
}
diff --git a/tests/org/apache/xalan/xpath3/XPathExprFunctionCallSuffixTests.java b/tests/org/apache/xalan/xpath3/XPathExprFunctionCallSuffixTests.java
index fb226a281..858ea65b0 100644
--- a/tests/org/apache/xalan/xpath3/XPathExprFunctionCallSuffixTests.java
+++ b/tests/org/apache/xalan/xpath3/XPathExprFunctionCallSuffixTests.java
@@ -87,5 +87,75 @@ public class XPathExprFunctionCallSuffixTests extends XSLTransformTestsUtil {
runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
}
+
+ @Test
+ public void xpathExprFunctionCallSuffixTest5() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.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 xpathExprFunctionCallSuffixTest6() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.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 xpathExprFunctionCallSuffixTest7() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.xml";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test7.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test7.out";
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
+
+ @Test
+ public void xpathExprFunctionCallSuffixTest8() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.xml";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test8.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test8.out";
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
+
+ @Test
+ public void xpathExprFunctionCallSuffixTest9() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test3.xml";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test9.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test9.out";
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
+
+ @Test
+ public void xpathExprFunctionCallSuffixTest10() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.xml";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test10.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test10.out";
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
+
+ @Test
+ public void xpathExprFunctionCallSuffixTest11() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.xml";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test11.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test11.out";
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
}
diff --git a/tests/xpath_function_call_suffix/gold/test10.out b/tests/xpath_function_call_suffix/gold/test10.out
new file mode 100644
index 000000000..841104b1c
--- /dev/null
+++ b/tests/xpath_function_call_suffix/gold/test10.out
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <item>info</item>
+ <item>a</item>
+ <item>val</item>
+ <item>a</item>
+ <item>val</item>
+ <item>a</item>
+ <item>val</item>
+ <item>a</item>
+ <item>val</item>
+ <item>a</item>
+ <item>val</item>
+</result>
diff --git a/tests/xpath_function_call_suffix/gold/test11.out b/tests/xpath_function_call_suffix/gold/test11.out
new file mode 100644
index 000000000..841104b1c
--- /dev/null
+++ b/tests/xpath_function_call_suffix/gold/test11.out
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <item>info</item>
+ <item>a</item>
+ <item>val</item>
+ <item>a</item>
+ <item>val</item>
+ <item>a</item>
+ <item>val</item>
+ <item>a</item>
+ <item>val</item>
+ <item>a</item>
+ <item>val</item>
+</result>
diff --git a/tests/xpath_function_call_suffix/gold/test5.out b/tests/xpath_function_call_suffix/gold/test5.out
new file mode 100644
index 000000000..a78cf820e
--- /dev/null
+++ b/tests/xpath_function_call_suffix/gold/test5.out
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <word>hello</word>
+ <word>there</word>
+ <word>how</word>
+ <word>are</word>
+ <word>you</word>
+</result>
diff --git a/tests/xpath_function_call_suffix/gold/test6.out b/tests/xpath_function_call_suffix/gold/test6.out
new file mode 100644
index 000000000..a78cf820e
--- /dev/null
+++ b/tests/xpath_function_call_suffix/gold/test6.out
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <word>hello</word>
+ <word>there</word>
+ <word>how</word>
+ <word>are</word>
+ <word>you</word>
+</result>
diff --git a/tests/xpath_function_call_suffix/gold/test7.out b/tests/xpath_function_call_suffix/gold/test7.out
new file mode 100644
index 000000000..bcad81fa6
--- /dev/null
+++ b/tests/xpath_function_call_suffix/gold/test7.out
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <value sqrt="1.414" inp="2"/>
+ <value sqrt="2" inp="4"/>
+ <value sqrt="2.449" inp="6"/>
+ <value sqrt="2.828" inp="8"/>
+ <value sqrt="3.162" inp="10"/>
+</result>
diff --git a/tests/xpath_function_call_suffix/gold/test8.out b/tests/xpath_function_call_suffix/gold/test8.out
new file mode 100644
index 000000000..7d6457d18
--- /dev/null
+++ b/tests/xpath_function_call_suffix/gold/test8.out
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+ <value sqr="4" inp="2"/>
+ <value sqr="16" inp="4"/>
+ <value sqr="36" inp="6"/>
+ <value sqr="64" inp="8"/>
+ <value sqr="100" inp="10"/>
+</result>
diff --git a/tests/xpath_function_call_suffix/gold/test9.out b/tests/xpath_function_call_suffix/gold/test9.out
new file mode 100644
index 000000000..fe6cf8ba8
--- /dev/null
+++ b/tests/xpath_function_call_suffix/gold/test9.out
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?><result sumOfSquares="220">
+ <item>4</item>
+ <item>16</item>
+ <item>36</item>
+ <item>64</item>
+ <item>100</item>
+</result>
diff --git a/tests/xpath_function_call_suffix/test10.xsl b/tests/xpath_function_call_suffix/test10.xsl
new file mode 100644
index 000000000..2fd568a7f
--- /dev/null
+++ b/tests/xpath_function_call_suffix/test10.xsl
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- use with test2.xml -->
+
+ <!-- An XSLT test case to test, XPath path expression
+ having a function call suffix.
+ -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:template match="/">
+ <result>
+ <xsl:for-each select="(//* | //@*)/local-name(.)">
+ <item>
+ <xsl:value-of select="."/>
+ </item>
+ </xsl:for-each>
+ </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>
diff --git a/tests/xpath_function_call_suffix/test11.xsl b/tests/xpath_function_call_suffix/test11.xsl
new file mode 100644
index 000000000..a76cb2052
--- /dev/null
+++ b/tests/xpath_function_call_suffix/test11.xsl
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- use with test2.xml -->
+
+ <!-- An XSLT test case to test, XPath path expression
+ having a function call suffix.
+ -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:template match="/">
+ <result>
+ <xsl:for-each select="(//* | //@*)/name(.)">
+ <item>
+ <xsl:value-of select="."/>
+ </item>
+ </xsl:for-each>
+ </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>
diff --git a/tests/xpath_function_call_suffix/test2.xml b/tests/xpath_function_call_suffix/test2.xml
new file mode 100644
index 000000000..82f9b43e8
--- /dev/null
+++ b/tests/xpath_function_call_suffix/test2.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<info>
+ <a val="2">a1</a>
+ <a val="4">a2</a>
+ <a val="6">a3</a>
+ <a val="8">a4</a>
+ <a val="10">a5</a>
+</info>
diff --git a/tests/xpath_function_call_suffix/test3.xml b/tests/xpath_function_call_suffix/test3.xml
new file mode 100644
index 000000000..079904acb
--- /dev/null
+++ b/tests/xpath_function_call_suffix/test3.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<info>
+ <a>2</a>
+ <a>4</a>
+ <a>6</a>
+ <a>8</a>
+ <a>10</a>
+</info>
diff --git a/tests/xpath_function_call_suffix/test5.xsl b/tests/xpath_function_call_suffix/test5.xsl
new file mode 100644
index 000000000..2681289f6
--- /dev/null
+++ b/tests/xpath_function_call_suffix/test5.xsl
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:map="http://www.w3.org/2005/xpath-functions/map"
+ exclude-result-prefixes="map"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- use with test2.xml -->
+
+ <!-- An XSLT test case to test, XPath path expression
+ having a function call suffix.
+ -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:variable name="map1" select="map {2 : 'hello', 4 : 'there', 6 : 'how', 8 : 'are', 10 : 'you'}" as="map(*)"/>
+
+ <xsl:template match="/info">
+ <result>
+ <xsl:for-each select="a/@val/map:get($map1, number(.))">
+ <word>
+ <xsl:value-of select="."/>
+ </word>
+ </xsl:for-each>
+ </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>
diff --git a/tests/xpath_function_call_suffix/test6.xsl b/tests/xpath_function_call_suffix/test6.xsl
new file mode 100644
index 000000000..331f39d88
--- /dev/null
+++ b/tests/xpath_function_call_suffix/test6.xsl
@@ -0,0 +1,48 @@
+<?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"
+ xmlns:map="http://www.w3.org/2005/xpath-functions/map"
+ exclude-result-prefixes="xs map"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- use with test2.xml -->
+
+ <!-- An XSLT test case to test, XPath path expression
+ having a function call suffix.
+ -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:variable name="map1" select="map {2 : 'hello', 4 : 'there', 6 : 'how', 8 : 'are', 10 : 'you'}" as="map(*)"/>
+
+ <xsl:template match="/info">
+ <result>
+ <xsl:for-each select="a/@val/map:get($map1, xs:integer(.))">
+ <word>
+ <xsl:value-of select="."/>
+ </word>
+ </xsl:for-each>
+ </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>
diff --git a/tests/xpath_function_call_suffix/test7.xsl b/tests/xpath_function_call_suffix/test7.xsl
new file mode 100644
index 000000000..479207e99
--- /dev/null
+++ b/tests/xpath_function_call_suffix/test7.xsl
@@ -0,0 +1,44 @@
+<?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"
+ xmlns:math="http://www.w3.org/2005/xpath-functions/math"
+ exclude-result-prefixes="xs math"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- use with test2.xml -->
+
+ <!-- An XSLT test case to test, XPath path expression
+ having a function call suffix.
+ -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:template match="/info">
+ <result>
+ <xsl:for-each select="a/@val/math:sqrt(xs:double(.))">
+ <value inp="{round(. * ., 3)}" sqrt="{round(., 3)}"/>
+ </xsl:for-each>
+ </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>
diff --git a/tests/xpath_function_call_suffix/test8.xsl b/tests/xpath_function_call_suffix/test8.xsl
new file mode 100644
index 000000000..3b8e51996
--- /dev/null
+++ b/tests/xpath_function_call_suffix/test8.xsl
@@ -0,0 +1,52 @@
+<?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"
+ xmlns:math="http://www.w3.org/2005/xpath-functions/math"
+ xmlns:fn0="http://fn0"
+ exclude-result-prefixes="xs math fn0"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- use with test2.xml -->
+
+ <!-- An XSLT test case to test, XPath path expression
+ having a function call suffix.
+ -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:template match="/info">
+ <result>
+ <xsl:for-each select="a/@val/fn0:sqr(xs:double(.))">
+ <value inp="{math:sqrt(xs:double(.))}" sqr="{.}"/>
+ </xsl:for-each>
+ </result>
+ </xsl:template>
+
+ <!-- An XSL stylesheet function, to find square of
+ the function argument. -->
+ <xsl:function name="fn0:sqr" as="xs:double">
+ <xsl:param name="num" as="xs:double"/>
+ <xsl:sequence select="$num * $num"/>
+ </xsl:function>
+
+ <!--
+ * 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>
diff --git a/tests/xpath_function_call_suffix/test9.xsl b/tests/xpath_function_call_suffix/test9.xsl
new file mode 100644
index 000000000..5205d9634
--- /dev/null
+++ b/tests/xpath_function_call_suffix/test9.xsl
@@ -0,0 +1,48 @@
+<?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"
+ xmlns:math="http://www.w3.org/2005/xpath-functions/math"
+ exclude-result-prefixes="xs math"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- use with test3.xml -->
+
+ <!-- An XSLT test case to test, XPath path expression
+ having a function call suffix.
+ -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:template match="/info">
+ <xsl:variable name="squareSeq" select="a/math:pow(xs:double(.), 2)"/>
+ <result sumOfSquares="{sum($squareSeq)}">
+ <xsl:for-each select="$squareSeq">
+ <item>
+ <xsl:value-of select="."/>
+ </item>
+ </xsl:for-each>
+ </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