You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by mu...@apache.org on 2023/07/09 16:39:50 UTC
[xalan-java] branch xalan-j_xslt3.0 updated: committing improvements to implementation of, xpath 3.1 dynamic function calls. also committing a related working test case 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 9d87cd23 committing improvements to implementation of, xpath 3.1 dynamic function calls. also committing a related working test case as well.
new 6cf8008f Merge pull request #23 from mukulga/xalan-j_xslt3.0_mukul
9d87cd23 is described below
commit 9d87cd2343a3ad7ebeb9414261c7619e03257d1a
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Sun Jul 9 22:00:15 2023 +0530
committing improvements to implementation of, xpath 3.1 dynamic function calls. also committing a related working test case as well.
---
src/org/apache/xpath/compiler/XPathParser.java | 76 +++++++++++++++++++---
.../xpath/functions/DynamicFunctionCall.java | 21 +++---
tests/dynamic_function_call/gold/test8.out | 5 ++
tests/dynamic_function_call/test1_d.xml | 16 +++++
tests/dynamic_function_call/test8.xsl | 45 +++++++++++++
.../xalan/xpath3/DynamicFunctionCallTests.java | 10 +++
6 files changed, 155 insertions(+), 18 deletions(-)
diff --git a/src/org/apache/xpath/compiler/XPathParser.java b/src/org/apache/xpath/compiler/XPathParser.java
index c5493cf6..3fdbfd37 100644
--- a/src/org/apache/xpath/compiler/XPathParser.java
+++ b/src/org/apache/xpath/compiler/XPathParser.java
@@ -90,14 +90,16 @@ public class XPathParser
private List<String> fXpathOpArrTokensList = null;
+ private boolean fDynamicFunctionCallArgumentMarker = false;
+
+ private boolean fIsXpathPredicateParsingActive = false;
+
static InlineFunction fInlineFunction = null;
static DynamicFunctionCall fDynamicFunctionCall = null;
static IfExpr fIfExpr = null;
- private boolean fIsXpathPredicateParsingActive = false;
-
/**
* The parser constructor.
*/
@@ -622,6 +624,52 @@ public class XPathParser
return (funcBodyXPathExprStrBuff.toString()).trim();
}
+
+ private boolean isXpathDynamicFuncCallParseAhead(List<String> argDetailsStrPartsList,
+ String delim) {
+ boolean isXpathDynamicFuncCallParseAhead = false;
+
+ if (lookahead('(', 1)) {
+ // handles the case, where the function call argument
+ // is itself another function call.
+ fDynamicFunctionCallArgumentMarker = true;
+ argDetailsStrPartsList.add(m_token);
+ nextToken();
+ isXpathDynamicFuncCallParseAhead = true;
+ }
+ else if (tokenIs(')') && lookahead(',', 1)) {
+ argDetailsStrPartsList.add(m_token);
+ nextToken();
+ argDetailsStrPartsList.add(delim);
+ nextToken();
+ fDynamicFunctionCallArgumentMarker = false;
+ isXpathDynamicFuncCallParseAhead = true;
+ }
+ else if (lookahead(',', 1)) {
+ argDetailsStrPartsList.add(m_token);
+ nextToken();
+ if (!fDynamicFunctionCallArgumentMarker) {
+ argDetailsStrPartsList.add(delim);
+ nextToken();
+ }
+ else {
+ argDetailsStrPartsList.add(m_token);
+ nextToken();
+ }
+ isXpathDynamicFuncCallParseAhead = true;
+ }
+ else if (!tokenIs(')')) {
+ argDetailsStrPartsList.add(m_token);
+ nextToken();
+ isXpathDynamicFuncCallParseAhead = true;
+ }
+ else if (fDynamicFunctionCallArgumentMarker) {
+ argDetailsStrPartsList.add(m_token);
+ nextToken();
+ }
+
+ return isXpathDynamicFuncCallParseAhead;
+ }
/**
* Notify the user of an assertion error, and probably throw an
@@ -1670,23 +1718,31 @@ public class XPathParser
List<String> argDetailsStrPartsList = new ArrayList<String>();
- while (!tokenIs(')') && m_token != null)
+ // we create here a temporary function call argument delimiter
+ // string, for this processing.
+ long currentTimeMills = System.currentTimeMillis();
+ String delimSuffix = (Long.valueOf(currentTimeMills)).toString();
+ String delim = "t0_" + delimSuffix;
+
+ while (m_token != null && isXpathDynamicFuncCallParseAhead(
+ argDetailsStrPartsList, delim))
{
- argDetailsStrPartsList.add(m_token);
- nextToken();
+ // no op here
}
+ fDynamicFunctionCallArgumentMarker = false;
+
int startIdx = 0;
- int idxComma;
- while (argDetailsStrPartsList.contains(",") &&
- (idxComma = argDetailsStrPartsList.indexOf(",")) != -1) {
- List<String> lst1 = argDetailsStrPartsList.subList(startIdx, idxComma);
+ int idxDelim;
+ while (argDetailsStrPartsList.contains(delim) &&
+ (idxDelim = argDetailsStrPartsList.indexOf(delim)) != -1) {
+ List<String> lst1 = argDetailsStrPartsList.subList(startIdx, idxDelim);
String xpathStr = getXPathStrFromComponentParts(lst1);
argList.add(xpathStr);
- List<String> lst2 = argDetailsStrPartsList.subList(idxComma + 1,
+ List<String> lst2 = argDetailsStrPartsList.subList(idxDelim + 1,
argDetailsStrPartsList.size());
argDetailsStrPartsList = lst2;
diff --git a/src/org/apache/xpath/functions/DynamicFunctionCall.java b/src/org/apache/xpath/functions/DynamicFunctionCall.java
index 5c97cf64..6ebc6451 100644
--- a/src/org/apache/xpath/functions/DynamicFunctionCall.java
+++ b/src/org/apache/xpath/functions/DynamicFunctionCall.java
@@ -51,6 +51,12 @@ public class DynamicFunctionCall extends Expression {
private String funcRefVarName;
private List<String> argList;
+
+ // the following two fields of this class, are used during
+ // XPath.fixupVariables(..) action as performed within object of
+ // this class.
+ private Vector fVars;
+ private int fGlobalsSize;
public String getFuncRefVarName() {
return funcRefVarName;
@@ -104,14 +110,12 @@ public class DynamicFunctionCall extends Expression {
String funcParamName = funcParamNameList.get(idx);
String argXPathStr = argList.get(idx);
- XObject argValue = null;
- if (argXPathStr.startsWith("$")) {
- argValue = exprContext.getVariableOrParam(new QName(argXPathStr.substring(1)));
- }
- else {
- XPath argXpath = new XPath(argXPathStr, srcLocator, null, XPath.SELECT, null);
- argValue = argXpath.execute(xctxt, contextNode, null);
+
+ XPath argXpath = new XPath(argXPathStr, srcLocator, null, XPath.SELECT, null);
+ if (fVars != null) {
+ argXpath.fixupVariables(fVars, fGlobalsSize);
}
+ XObject argValue = argXpath.execute(xctxt, contextNode, null);
inlineFunctionVarMap.put(new QName(funcParamName), argValue);
}
@@ -127,7 +131,8 @@ public class DynamicFunctionCall extends Expression {
@Override
public void fixupVariables(Vector vars, int globalsSize) {
- // no op
+ fVars = (Vector)(vars.clone());
+ fGlobalsSize = globalsSize;
}
@Override
diff --git a/tests/dynamic_function_call/gold/test8.out b/tests/dynamic_function_call/gold/test8.out
new file mode 100644
index 00000000..6719da81
--- /dev/null
+++ b/tests/dynamic_function_call/gold/test8.out
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?><list>
+ <person>Id : 1, Name : Gary Gregory</person>
+ <person>Id : 2, Name : Joseph Kesselman</person>
+ <person>Id : 3, Name : Leonhard Euler</person>
+</list>
diff --git a/tests/dynamic_function_call/test1_d.xml b/tests/dynamic_function_call/test1_d.xml
new file mode 100644
index 00000000..79c2432c
--- /dev/null
+++ b/tests/dynamic_function_call/test1_d.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<list>
+ <person>
+ <fName>Gary</fName>
+ <lName>Gregory</lName>
+ </person>
+ <person>
+ <fName>Joseph</fName>
+ <lName>Kesselman</lName>
+ </person>
+ <person>
+ <fName>Leonhard</fName>
+ <lName>Euler</lName>
+ </person>
+</list>
+
\ No newline at end of file
diff --git a/tests/dynamic_function_call/test8.xsl b/tests/dynamic_function_call/test8.xsl
new file mode 100644
index 00000000..db819564
--- /dev/null
+++ b/tests/dynamic_function_call/test8.xsl
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="3.0">
+
+ <!-- Author: mukulg@apache.org -->
+
+ <!-- use with test1_d.xml -->
+
+ <!-- Test case description : Specifying complex valued arguments to
+ XPath dynamic function call (for e.g, within this XSLT stylesheet,
+ dynamic function call arguments are themselves function calls. -->
+
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:variable name="trfNameStr" select="function($pos, $str) { concat('Id : ', $pos, ', Name : ', $str) }"/>
+
+ <xsl:template match="/list">
+ <list>
+ <xsl:for-each select="person">
+ <person>
+ <xsl:copy-of select="$trfNameStr(position(), concat(fName, ' ', lName))"/>
+ </person>
+ </xsl:for-each>
+ </list>
+ </xsl:template>
+
+ <!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/tests/org/apache/xalan/xpath3/DynamicFunctionCallTests.java b/tests/org/apache/xalan/xpath3/DynamicFunctionCallTests.java
index e7d2bb3c..3a12aa06 100644
--- a/tests/org/apache/xalan/xpath3/DynamicFunctionCallTests.java
+++ b/tests/org/apache/xalan/xpath3/DynamicFunctionCallTests.java
@@ -116,5 +116,15 @@ public class DynamicFunctionCallTests extends XslTransformTestsUtil {
runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
}
+
+ @Test
+ public void xslDynamicFunctionCallTest8() {
+ String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_d.xml";
+ String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test8.xsl";
+
+ String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test8.out";
+
+ runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xalan.apache.org
For additional commands, e-mail: commits-help@xalan.apache.org