You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by mu...@apache.org on 2023/09/06 13:52:54 UTC

[xalan-java] branch xalan-j_xslt3.0 updated: committing minor fixes to, xpath 3.1 'let' expression and 'dynamic function call' evaluations, and few other minor codebase improvements as well. also committing a new working test case, for xpath 3.1 'let' expression.

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 3140c284 committing minor fixes to, xpath 3.1 'let' expression and 'dynamic function call' evaluations, and few other minor codebase improvements as well. also committing a new working test case, for xpath 3.1 'let' expression.
     new 803e2ec1 Merge pull request #77 from mukulga/xalan-j_xslt3.0_mukul
3140c284 is described below

commit 3140c28464ead87a9914c48f0200a1eaf9d9e7b1
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Wed Sep 6 19:18:34 2023 +0530

    committing minor fixes to, xpath 3.1 'let' expression and 'dynamic function call' evaluations, and few other minor codebase improvements as well. also committing a new working test case, for xpath 3.1 'let' expression.
---
 src/org/apache/xalan/templates/ElemValueOf.java    | 20 +------
 .../xalan/templates/XSConstructorFunctionUtil.java | 22 ++------
 src/org/apache/xpath/compiler/XPathParser.java     |  6 +-
 src/org/apache/xpath/composite/LetExpr.java        | 18 ++++--
 .../xpath/functions/DynamicFunctionCall.java       |  8 ++-
 tests/let_expr/gold/test11.out                     |  5 ++
 tests/let_expr/test11.xsl                          | 65 ++++++++++++++++++++++
 tests/org/apache/xalan/xpath3/LetExprTests.java    | 10 ++++
 8 files changed, 110 insertions(+), 44 deletions(-)

diff --git a/src/org/apache/xalan/templates/ElemValueOf.java b/src/org/apache/xalan/templates/ElemValueOf.java
index 35dd9bf9..8614c64d 100644
--- a/src/org/apache/xalan/templates/ElemValueOf.java
+++ b/src/org/apache/xalan/templates/ElemValueOf.java
@@ -43,9 +43,6 @@ import org.apache.xpath.objects.XNumber;
 import org.apache.xpath.objects.XObject;
 import org.apache.xpath.objects.XString;
 import org.apache.xpath.operations.Operation;
-import org.apache.xpath.operations.Range;
-import org.apache.xpath.operations.SimpleMapOperator;
-import org.apache.xpath.operations.StrConcat;
 import org.apache.xpath.operations.Variable;
 import org.apache.xpath.xs.types.XSAnyType;
 import org.apache.xpath.xs.types.XSNumericType;
@@ -359,21 +356,8 @@ public class ElemValueOf extends ElemTemplateElement {
                       }
                       (new XString(strValue)).dispatchCharactersEvents(rth);
                   }
-                  else if (expr instanceof Operation) {
-                     Operation opn = (Operation)expr;
-                     
-                     XObject evalResult = null;
-                     if ((opn instanceof Range) || (opn instanceof StrConcat) || 
-                                                                       (opn instanceof SimpleMapOperator)) {
-                        evalResult = opn.execute(xctxt);                        
-                     }
-                     else {
-                        XObject leftOperand = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn(
-                                                                                           xctxt, opn.getLeftOperand());
-                        XObject rightOperand = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn(
-                                                                                           xctxt, opn.getRightOperand());
-                        evalResult = opn.operate(leftOperand, rightOperand);
-                     }
+                  else if (expr instanceof Operation) {                     
+                     XObject evalResult = expr.execute(xctxt);
                      
                      String strValue = null;
                      
diff --git a/src/org/apache/xalan/templates/XSConstructorFunctionUtil.java b/src/org/apache/xalan/templates/XSConstructorFunctionUtil.java
index be8e2a15..39fcf50c 100644
--- a/src/org/apache/xalan/templates/XSConstructorFunctionUtil.java
+++ b/src/org/apache/xalan/templates/XSConstructorFunctionUtil.java
@@ -27,7 +27,6 @@ import org.apache.xpath.compiler.Keywords;
 import org.apache.xpath.functions.FuncExtFunction;
 import org.apache.xpath.objects.ResultSequence;
 import org.apache.xpath.objects.XObject;
-import org.apache.xpath.operations.Operation;
 import org.apache.xpath.xs.types.XSBoolean;
 import org.apache.xpath.xs.types.XSDate;
 import org.apache.xpath.xs.types.XSDayTimeDuration;
@@ -54,8 +53,8 @@ import org.xml.sax.SAXException;
 public class XSConstructorFunctionUtil {
     
     /**
-     * Process an XPath expression of type FuncExtFunction, XPath operation, 
-     * and also few XPath default expression processing.
+     * Evaluate an XPath expression of type FuncExtFunction, and also few 
+     * other kinds of XPath expressions.
      */
     public static XObject processFuncExtFunctionOrXPathOpn(XPathContext xctxt, Expression expr)
                                                                     throws TransformerException, SAXException {        
@@ -64,8 +63,8 @@ public class XSConstructorFunctionUtil {
         SourceLocator srcLocator = xctxt.getSAXLocator();
 
         // XalanJ's extension function handler mechanism, treats at a syntactic level,
-        // XPath 3.1 constructor function calls like xs:type_name(..) as calls to XSLT/XPath
-        // extension functions. If the XML namespace of XSLT/XPath function calls is an XML Schema
+        // XPath 3.1 constructor function calls like xs:type_name(..) as calls to XalanJ 
+        // extension functions. If the XML namespace of these function calls is an XML Schema
         // namespace, then we use this fact to treat such function calls as XPath 3.1 constructor 
         // function calls, as has been implemented within code below.
         
@@ -226,19 +225,10 @@ public class XSConstructorFunctionUtil {
                     default:
                        // no op
                   }
-            }
-        }
-        else if (expr instanceof Operation) {
-            // We need to call this method recursively, for the possibility of more than one
-            // XPath expression evaluation operator present within an XPath expression 
-            // (for e.g, a + b - c).
-            Operation opn = (Operation)expr;
-            XObject leftOperand = processFuncExtFunctionOrXPathOpn(xctxt, opn.getLeftOperand());
-            XObject rightOperand = processFuncExtFunctionOrXPathOpn(xctxt, opn.getRightOperand());
-            evalResult = opn.operate(leftOperand, rightOperand);
+             }
         }
         else {
-            evalResult = expr.execute(xctxt);   
+           evalResult = expr.execute(xctxt);   
         }
 
         return evalResult;
diff --git a/src/org/apache/xpath/compiler/XPathParser.java b/src/org/apache/xpath/compiler/XPathParser.java
index 1d627afe..cbf0ee11 100644
--- a/src/org/apache/xpath/compiler/XPathParser.java
+++ b/src/org/apache/xpath/compiler/XPathParser.java
@@ -96,11 +96,11 @@ public class XPathParser
    * XPath language key words and symbols that need this support.
    */
   private static final String[] XPATH_OP_ARR = new String[] 
-                                                     {"div", "or", "and", "mod", "to", 
+                                                     { "div", "or", "and", "mod", "to", 
                                                       "eq", "ne", "lt", "gt", "le", "ge", 
                                                       "for", "in", "return", "if", "then", 
                                                       "else", "some", "every", "satisfies", 
-                                                      "let", ":=", "-", "||"};
+                                                      "let", ":=", "-", "||", "instance", "of" };
   
   // If the XPath expression is () (i.e, representing an xdm empty sequence),
   // we translate that within this XPath parser implementation, to an XPath
@@ -2012,7 +2012,7 @@ public class XPathParser
           
           int op1 = m_ops.getOp(OpMap.MAPINDEX_LENGTH) - addPos;
           
-          fXpathSequenceTypeExpr = SequenceTypeExpr();
+          fXpathSequenceTypeExpr = SequenceTypeExpr();          
           m_ops.setOp(addPos + OpMap.MAPINDEX_LENGTH, 
                                                   m_ops.getOp(addPos + op1 + 1) + op1);
           addPos += 2;
diff --git a/src/org/apache/xpath/composite/LetExpr.java b/src/org/apache/xpath/composite/LetExpr.java
index a3ee20b8..3861303e 100644
--- a/src/org/apache/xpath/composite/LetExpr.java
+++ b/src/org/apache/xpath/composite/LetExpr.java
@@ -17,6 +17,7 @@
 package org.apache.xpath.composite;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Vector;
@@ -79,9 +80,7 @@ public class LetExpr extends Expression {
         
        SourceLocator srcLocator = xctxt.getSAXLocator();
         
-       int contextNode = xctxt.getContextNode();
-       
-       Map<QName, XObject> xpathVarMap = xctxt.getXPathVarMap();
+       int contextNode = xctxt.getContextNode();              
        
        ElemTemplateElement elemTemplateElement = (ElemTemplateElement)xctxt.getNamespaceContext();
        List<XMLNSDecl> prefixTable = null;
@@ -89,7 +88,9 @@ public class LetExpr extends Expression {
           prefixTable = (List<XMLNSDecl>)elemTemplateElement.getPrefixTable();
        }
        
-       for (int idx = 0; idx < fLetExprVarBindingList.size(); idx++) {
+       Map<QName, XObject> letExprVarBindingMap = new HashMap<QName, XObject>();
+       
+       for (int idx = 0; idx < fLetExprVarBindingList.size(); idx++) {          
           LetExprVarBinding letExprVarBinding = fLetExprVarBindingList.get(idx);
           String varName = letExprVarBinding.getVarName();
           String fXpathExprStr = letExprVarBinding.getXpathExprStr();
@@ -109,9 +110,14 @@ public class LetExpr extends Expression {
                                                                                      xctxt.getNamespaceContext());
           
           m_xpathVarList.add(new QName(varName));
-          xpathVarMap.put(new QName(varName), varBindingEvalResult);
+          
+          letExprVarBindingMap.put(new QName(varName), varBindingEvalResult);
        }
        
+       Map<QName, XObject> xpathVarMap = xctxt.getXPathVarMap();
+       
+       xpathVarMap.putAll(letExprVarBindingMap);
+       
        if (prefixTable != null) {
           fReturnExprXPathStr = XslTransformEvaluationHelper.replaceNsUrisWithPrefixesOnXPathStr(
                                                                                 fReturnExprXPathStr, prefixTable);
@@ -127,7 +133,7 @@ public class LetExpr extends Expression {
        evalResult = returnExprXpath.execute(xctxt, contextNode, xctxt.getNamespaceContext());
        
        if (evalResult == null) {
-          // return an empty sequence, here
+          // Return an empty sequence, here
           evalResult = new ResultSequence();   
        }
         
diff --git a/src/org/apache/xpath/functions/DynamicFunctionCall.java b/src/org/apache/xpath/functions/DynamicFunctionCall.java
index 3c2fbc2f..20a8a2c6 100644
--- a/src/org/apache/xpath/functions/DynamicFunctionCall.java
+++ b/src/org/apache/xpath/functions/DynamicFunctionCall.java
@@ -16,6 +16,7 @@
  */
 package org.apache.xpath.functions;
 
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Vector;
@@ -138,6 +139,8 @@ public class DynamicFunctionCall extends Expression {
                prefixTable = (List<XMLNSDecl>)elemTemplateElement.getPrefixTable();
            }
            
+           Map<QName, XObject> functionParamAndArgMap = new HashMap<QName, XObject>();
+           
            for (int idx = 0; idx < funcParamNameList.size(); idx++) {              
               String funcParamName = funcParamNameList.get(idx);
               
@@ -157,9 +160,12 @@ public class DynamicFunctionCall extends Expression {
               XObject argValue = argXPath.execute(xctxt, contextNode, xctxt.getNamespaceContext());
               
               m_xpathVarList.add(new QName(funcParamName));
-              inlineFunctionVarMap.put(new QName(funcParamName), argValue);
+              
+              functionParamAndArgMap.put(new QName(funcParamName), argValue);
            }
            
+           inlineFunctionVarMap.putAll(functionParamAndArgMap);
+           
            if (prefixTable != null) {
               inlineFnXPathStr = XslTransformEvaluationHelper.replaceNsUrisWithPrefixesOnXPathStr(inlineFnXPathStr, 
                                                                                                            prefixTable);
diff --git a/tests/let_expr/gold/test11.out b/tests/let_expr/gold/test11.out
new file mode 100644
index 00000000..d08a3848
--- /dev/null
+++ b/tests/let_expr/gold/test11.out
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>false</one>
+  <two>false</two>
+  <three>true</three>
+</result>
diff --git a/tests/let_expr/test11.xsl b/tests/let_expr/test11.xsl
new file mode 100644
index 00000000..cf84aa65
--- /dev/null
+++ b/tests/let_expr/test11.xsl
@@ -0,0 +1,65 @@
+<?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 -->              
+   
+   <!-- An XSLT stylesheet test case, to test the evaluation of 
+        an XPath 3.1 "let" expression, along with XPath inline
+        function expression and dynamic function call. -->                  
+    
+    <xsl:output method="xml" indent="yes"/>
+    
+    <!-- A user-defined inline function expression, to check whether a function argument value
+         is an instance of type xs:integer. -->
+    <xsl:variable name="fIsValXsInteger" select="function($val) { $val instance of xs:integer }"/>
+    
+    <!-- A user-defined inline function expression, to check whether a function argument value
+         is an instance of type xs:string. -->
+    <xsl:variable name="fIsValXsString" select="function($val) { $val instance of xs:string }"/>
+    
+    <!-- A user-defined inline function expression, to do boolean 'and' operation on two 
+         boolean argument values. -->
+    <xsl:variable name="fnAnd" select="function($val1, $val2) { let $result1 := $val1, 
+                                                                    $result2 := $val2 
+                                                                          return ($result1 and $result2) }"/>
+    
+    <xsl:template match="/">       
+       <result>
+          <one>
+             <xsl:value-of select="let $result1 := $fIsValXsInteger('5a'), 
+                                       $result2 := $fIsValXsString('hi') 
+                                                                return ($result1 and $result2)"/>
+          </one>
+          <two>
+             <xsl:value-of select="$fnAnd($fIsValXsInteger('5a'), $fIsValXsString('hi'))"/>
+          </two>
+          <three>
+             <xsl:variable name="var1" select="7"/>
+             <xsl:variable name="var2" select="'hi'"/>
+	         <xsl:value-of select="$fnAnd($fIsValXsInteger($var1), $fIsValXsString($var2))"/>
+          </three>
+       </result>
+    </xsl:template>
+    
+    <!--
+      * Licensed to the Apache Software Foundation (ASF) under one
+      * or more contributor license agreements. See the NOTICE file
+      * distributed with this work for additional information
+      * regarding copyright ownership. The ASF licenses this file
+      * to you under the Apache License, Version 2.0 (the  "License");
+      * you may not use this file except in compliance with the License.
+      * You may obtain a copy of the License at
+      *
+      *     http://www.apache.org/licenses/LICENSE-2.0
+      *
+      * Unless required by applicable law or agreed to in writing, software
+      * distributed under the License is distributed on an "AS IS" BASIS,
+      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      * See the License for the specific language governing permissions and
+      * limitations under the License.
+   -->
+    
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/tests/org/apache/xalan/xpath3/LetExprTests.java b/tests/org/apache/xalan/xpath3/LetExprTests.java
index 8ec01d0f..b78d5b6d 100644
--- a/tests/org/apache/xalan/xpath3/LetExprTests.java
+++ b/tests/org/apache/xalan/xpath3/LetExprTests.java
@@ -146,5 +146,15 @@ public class LetExprTests extends XslTransformTestsUtil {
         
         runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
     }
+    
+    @Test
+    public void xslLetExprTest11() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test11.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test11.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test11.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