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/25 09:59:20 UTC

[xalan-java] branch xalan-j_xslt3.0 updated: committing implementation of xpath 3.1 string concatenation operator

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 0eae0da8 committing implementation of xpath 3.1 string concatenation operator
     new e3c1fc4d Merge pull request #35 from mukulga/xalan-j_xslt3.0_mukul
0eae0da8 is described below

commit 0eae0da8d9cce739fb9c5a8e8ca880dbdd6931f8
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Tue Jul 25 14:58:05 2023 +0530

    committing implementation of xpath 3.1 string concatenation operator
---
 src/org/apache/xalan/templates/ElemCopyOf.java     |  8 +++
 src/org/apache/xalan/templates/ElemValueOf.java    | 67 ++++++++++++++++++--
 src/org/apache/xpath/compiler/Compiler.java        | 13 ++++
 src/org/apache/xpath/compiler/Lexer.java           |  8 +++
 src/org/apache/xpath/compiler/OpCodes.java         |  9 ++-
 src/org/apache/xpath/compiler/XPathParser.java     | 20 +++++-
 src/org/apache/xpath/operations/StrConcat.java     | 72 ++++++++++++++++++++++
 tests/dynamic_function_call/gold/test10.out        | 22 +++++++
 tests/dynamic_function_call/test10.xsl             | 46 ++++++++++++++
 tests/dynamic_function_call/test1_e.xml            |  9 +++
 .../xalan/xpath3/DynamicFunctionCallTests.java     | 10 +++
 tests/org/apache/xalan/xpath3/RangeExprTests.java  | 10 +++
 ...onCallTests.java => StringConcatExprTests.java} | 61 ++++--------------
 tests/org/apache/xalan/xslt3/AllXsl3Tests.java     |  3 +-
 tests/range_expr/gold/test13.out                   |  8 +++
 tests/range_expr/test12.xsl                        | 18 ++++++
 tests/range_expr/test13.xsl                        | 43 +++++++++++++
 tests/range_expr/test1_c.xml                       |  7 +++
 tests/stringConcatExpr/gold/test1.out              |  1 +
 tests/stringConcatExpr/gold/test2.out              |  1 +
 tests/stringConcatExpr/gold/test3.out              |  1 +
 tests/stringConcatExpr/gold/test4.out              |  4 ++
 tests/stringConcatExpr/gold/test5.out              |  7 +++
 tests/stringConcatExpr/test1.xsl                   | 38 ++++++++++++
 tests/stringConcatExpr/test1_a.xml                 |  6 ++
 tests/stringConcatExpr/test1_b.xml                 |  6 ++
 tests/stringConcatExpr/test2.xsl                   | 36 +++++++++++
 tests/stringConcatExpr/test3.xsl                   | 39 ++++++++++++
 tests/stringConcatExpr/test4.xsl                   | 39 ++++++++++++
 tests/stringConcatExpr/test5.xsl                   | 55 +++++++++++++++++
 30 files changed, 607 insertions(+), 60 deletions(-)

diff --git a/src/org/apache/xalan/templates/ElemCopyOf.java b/src/org/apache/xalan/templates/ElemCopyOf.java
index 54242ddb..2d3b308e 100644
--- a/src/org/apache/xalan/templates/ElemCopyOf.java
+++ b/src/org/apache/xalan/templates/ElemCopyOf.java
@@ -35,6 +35,7 @@ import org.apache.xpath.XPathContext;
 import org.apache.xpath.objects.ResultSequence;
 import org.apache.xpath.objects.XNumber;
 import org.apache.xpath.objects.XObject;
+import org.apache.xpath.xs.types.XSNumericType;
 import org.apache.xpath.xs.types.XSUntyped;
 import org.apache.xpath.xs.types.XSUntypedAtomic;
 
@@ -223,6 +224,13 @@ public class ElemCopyOf extends ElemTemplateElement
                     handler.characters(spaceCharArr, 0, 1);
                  }
              }
+             else if (sequenceItem instanceof XSNumericType) {
+                 String str = ((XSNumericType)sequenceItem).stringValue();
+                 handler.characters(str.toCharArray(), 0, str.length());
+                 if (idx < (resultSequence.size() - 1)) {                     
+                    handler.characters(spaceCharArr, 0, 1);
+                 }
+             }
              else if (sequenceItem instanceof XSUntyped) {
                  String str = ((XSUntyped)sequenceItem).stringValue();
                  handler.characters(str.toCharArray(), 0, str.length());
diff --git a/src/org/apache/xalan/templates/ElemValueOf.java b/src/org/apache/xalan/templates/ElemValueOf.java
index de37ab37..dc9706da 100644
--- a/src/org/apache/xalan/templates/ElemValueOf.java
+++ b/src/org/apache/xalan/templates/ElemValueOf.java
@@ -22,16 +22,22 @@ import javax.xml.transform.TransformerException;
 import org.apache.xalan.res.XSLTErrorResources;
 import org.apache.xalan.transformer.TransformerImpl;
 import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
 import org.apache.xml.serializer.SerializationHandler;
 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.functions.DynamicFunctionCall;
 import org.apache.xpath.functions.FuncExtFunction;
 import org.apache.xpath.functions.Function;
+import org.apache.xpath.objects.ResultSequence;
+import org.apache.xpath.objects.XNodeSet;
 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.StrConcat;
 import org.apache.xpath.operations.Variable;
 import org.apache.xpath.xs.types.XSAnyType;
 import org.w3c.dom.DOMException;
@@ -334,19 +340,48 @@ public class ElemValueOf extends ElemTemplateElement {
                   }
                   else if (expr instanceof Operation) {
                      Operation opn = (Operation)expr;
-                     XObject leftOperand = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn(
-                                                                                         xctxt, opn.getLeftOperand());
-                     XObject rightOperand = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn(
-                                                                                         xctxt, opn.getRightOperand());
-                     XObject evalResult = opn.operate(leftOperand, rightOperand);
+                     
+                     XObject evalResult = null;
+                     if ((opn instanceof Range) || (opn instanceof StrConcat)) {
+                        evalResult = opn.execute(xctxt);                        
+                     }
+                     else {
+                        XObject leftOperand = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn(
+                                                                                           xctxt, opn.getLeftOperand());
+                        XObject rightOperand = XSConstructorFunctionUtil.processFuncExtFunctionOrXPathOpn(
+                                                                                           xctxt, opn.getRightOperand());
+                        evalResult = opn.operate(leftOperand, rightOperand);
+                     }
                      
                      String strValue = null;
-                     if (evalResult instanceof XSAnyType) {
+                     
+                     if (evalResult instanceof ResultSequence) {
+                         ResultSequence rSeq = (ResultSequence)evalResult;
+                         
+                         StringBuffer strBuff = new StringBuffer();
+                         
+                         for (int idx = 0; idx < rSeq.size(); idx++) {
+                            XObject seqItem = rSeq.item(idx);
+                            String seqItemStrValue = (seqItem instanceof XSAnyType) ? 
+                                                                             ((XSAnyType)seqItem).stringValue() : 
+                                                                                                          seqItem.str(); 
+                            if (idx < (rSeq.size() - 1)) {
+                               strBuff.append(seqItemStrValue + " ");   
+                            }
+                            else {
+                               strBuff.append(seqItemStrValue); 
+                            }
+                         }
+                         
+                         strValue = strBuff.toString(); 
+                     }
+                     else if (evalResult instanceof XSAnyType) {
                          strValue = ((XSAnyType)evalResult).stringValue();
                      }
                      else {
                          strValue = evalResult.str();
                      }
+                     
                      (new XString(strValue)).dispatchCharactersEvents(rth);
                   }
                   else if (expr instanceof DynamicFunctionCall) {
@@ -358,6 +393,26 @@ public class ElemValueOf extends ElemTemplateElement {
                      
                      (new XString(strValue)).dispatchCharactersEvents(rth);
                   }
+                  else if (expr instanceof LocPathIterator) {
+                     LocPathIterator locPathIterator = (LocPathIterator)expr;
+                     
+                     DTMIterator dtmIter = locPathIterator.asIterator(xctxt, current);
+                     int nextNode;
+                     StringBuffer strBuff = new StringBuffer();
+                     while ((nextNode = dtmIter.nextNode()) != DTM.NULL)
+                     {
+                         XNodeSet singletonXPathNode = new XNodeSet(nextNode, xctxt);
+                         String nodeStrVal = singletonXPathNode.str();
+                         strBuff.append(nodeStrVal + " ");
+                     }
+                     
+                     String nodeSetStrValue = strBuff.toString();
+                     if (nodeSetStrValue.length() > 1) {
+                        nodeSetStrValue = nodeSetStrValue.substring(0, 
+                                                             nodeSetStrValue.length() - 1);
+                        (new XString(nodeSetStrValue)).dispatchCharactersEvents(rth);
+                     }
+                  }
                   else {
                      expr.executeCharsToContentHandler(xctxt, rth);
                   }
diff --git a/src/org/apache/xpath/compiler/Compiler.java b/src/org/apache/xpath/compiler/Compiler.java
index 32eafeff..5a2029f6 100644
--- a/src/org/apache/xpath/compiler/Compiler.java
+++ b/src/org/apache/xpath/compiler/Compiler.java
@@ -56,6 +56,7 @@ import org.apache.xpath.operations.Operation;
 import org.apache.xpath.operations.Or;
 import org.apache.xpath.operations.Plus;
 import org.apache.xpath.operations.Range;
+import org.apache.xpath.operations.StrConcat;
 import org.apache.xpath.operations.UnaryOperation;
 import org.apache.xpath.operations.Variable;
 import org.apache.xpath.operations.VcEquals;
@@ -171,6 +172,8 @@ public class Compiler extends OpMap
       expr = plus(opPos); break;
     case OpCodes.OP_TO :
       expr = range(opPos); break;
+    case OpCodes.OP_STR_CONCAT :
+      expr = strConcat(opPos); break;
     case OpCodes.OP_MINUS :
       expr = minus(opPos); break;
     case OpCodes.OP_MULT :
@@ -461,6 +464,16 @@ public class Compiler extends OpMap
   {
     return compileOperation(new Range(), opPos);   
   }
+  
+  /*
+   * Compile an XPath 3.1 "||" operation.
+   * 
+   * @param opPos The current position in the m_opMap array.
+   */
+  protected Expression strConcat(int opPos) throws TransformerException
+  {
+    return compileOperation(new StrConcat(), opPos);   
+  }
 
   /**
    * Compile a '-' operation.
diff --git a/src/org/apache/xpath/compiler/Lexer.java b/src/org/apache/xpath/compiler/Lexer.java
index f48b8e61..008854a1 100644
--- a/src/org/apache/xpath/compiler/Lexer.java
+++ b/src/org/apache/xpath/compiler/Lexer.java
@@ -254,6 +254,14 @@ class Lexer
       case '{' :   // added for XPath 3.1
       case '}' :   // added for XPath 3.1    
       case '|' :
+        if ((pat.length() > (i + 1)) && (pat.charAt(i + 1) == '|')) {
+          // added for XPath 3.1.
+          // to recognize the character sequence "||", as an XPath 
+          // language token.
+          addToTokenQueue(pat.substring(i, i + 2));
+          i += 1;
+          break;
+        }        
       case '/' :
       case '*' :
       case '+' :
diff --git a/src/org/apache/xpath/compiler/OpCodes.java b/src/org/apache/xpath/compiler/OpCodes.java
index 0e96a2aa..e7536927 100644
--- a/src/org/apache/xpath/compiler/OpCodes.java
+++ b/src/org/apache/xpath/compiler/OpCodes.java
@@ -689,8 +689,15 @@ public class OpCodes
   public static final int OP_IF_EXPR = 66;
   
   public static final int OP_SEQUENCE_CONSTRUCTOR_EXPR = 67;
+  
+  /**
+   * For XPath 3.1 string concatenation operator "||".
+   * 
+   * @xsl.usage advanced
+   */
+  public static final int OP_STR_CONCAT = 68;
 
   /** The next free ID. Please keep this up to date. */
-  private static final int NEXT_FREE_ID = 68;
+  private static final int NEXT_FREE_ID = 69;
   
 }
diff --git a/src/org/apache/xpath/compiler/XPathParser.java b/src/org/apache/xpath/compiler/XPathParser.java
index e92a618c..ffb49f7c 100644
--- a/src/org/apache/xpath/compiler/XPathParser.java
+++ b/src/org/apache/xpath/compiler/XPathParser.java
@@ -96,7 +96,7 @@ public class XPathParser
                                                       "eq", "ne", "lt", "gt", "le", "ge", 
                                                       "for", "in", "return", "if", "then", 
                                                       "else", "some", "every", "satisfies", 
-                                                      "let", ":=", "-"};
+                                                      "let", ":=", "-", "||"};
   
   private static final List<String> fXpathOpArrTokensList = Arrays.asList(XPATH_OP_ARR);
   
@@ -1548,6 +1548,7 @@ public class XPathParser
    * | RelationalExpr '<=' AdditiveExpr
    * | RelationalExpr '>=' AdditiveExpr
    * | RelationalExpr 'to' AdditiveExpr
+   * | RelationalExpr '||' AdditiveExpr
    * | RelationalExpr 'lt' AdditiveExpr
    * | RelationalExpr 'le' AdditiveExpr
    * | RelationalExpr 'gt' AdditiveExpr
@@ -1628,6 +1629,21 @@ public class XPathParser
             m_ops.getOp(addPos + op1 + 1) + op1);
           addPos += 2; 
       }
+      else if (tokenIs("||"))
+      {
+          // support for XPath 3.1 string concatenation operator, "||"
+          
+          nextToken();
+          
+          insertOp(addPos, 2, OpCodes.OP_STR_CONCAT);
+          
+          int op1 = m_ops.getOp(OpMap.MAPINDEX_LENGTH) - addPos;
+
+          addPos = RelationalExpr(addPos);
+          m_ops.setOp(addPos + OpMap.MAPINDEX_LENGTH, 
+            m_ops.getOp(addPos + op1 + 1) + op1);
+          addPos += 2; 
+      }
       else if (tokenIs("lt"))
       {
           // support for XPath 3.1 value comparison operator "lt"
@@ -1950,7 +1966,7 @@ public class XPathParser
     {
       PathExpr();
 
-      if (tokenIs('|'))
+      if (tokenIs('|') && !tokenIs("||"))
       {
         if (false == foundUnion)
         {
diff --git a/src/org/apache/xpath/operations/StrConcat.java b/src/org/apache/xpath/operations/StrConcat.java
new file mode 100644
index 00000000..96533a25
--- /dev/null
+++ b/src/org/apache/xpath/operations/StrConcat.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the  "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.xpath.operations;
+
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XString;
+
+/**
+ * The XPath 3.1 string concatenation "||" operation.
+ * 
+ * An XPath string concatenation "||" expression, may be used to concatenate 
+ * two string values. With XPath 3.1 language, an XPath expression $a || $b 
+ * is equivalent to fn:concat($a, $b).
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class StrConcat extends Operation
+{
+
+   private static final long serialVersionUID = -820873651965512508L;
+
+   /**
+   * Apply the operation to two operands, and return the result.
+   *
+   * @param left non-null reference to the evaluated left operand.
+   * @param right non-null reference to the evaluated right operand.
+   *
+   * @return non-null reference to the XObject that represents the result of the operation.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+    public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException {
+        
+      XObject result = null;
+      
+      XObject expr1 = m_left.execute(xctxt);
+      
+      XObject expr2 = m_right.execute(xctxt);
+      
+      result = new XString(expr1.str() + expr2.str());
+      
+      return result;
+    }
+    
+    /**
+     * Apply the operation to two operands, and return the result.
+     */
+    public XObject operate(XObject left, XObject right) {
+        XObject result =  new XString(left.str() + right.str());
+        
+        return result;
+    }
+
+}
diff --git a/tests/dynamic_function_call/gold/test10.out b/tests/dynamic_function_call/gold/test10.out
new file mode 100644
index 00000000..a03fa0f0
--- /dev/null
+++ b/tests/dynamic_function_call/gold/test10.out
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <detail origStr="abc1">
+    <derivedVal>abc</derivedVal>
+    <derivedSameVal>abc</derivedSameVal>
+  </detail>
+  <detail origStr="pqr2">
+    <derivedVal>pqr</derivedVal>
+    <derivedSameVal>pqr</derivedSameVal>
+  </detail>
+  <detail origStr="mno3">
+    <derivedVal>mno</derivedVal>
+    <derivedSameVal>mno</derivedSameVal>
+  </detail>
+  <detail origStr="uvw4">
+    <derivedVal>uvw</derivedVal>
+    <derivedSameVal>uvw</derivedSameVal>
+  </detail>
+  <detail origStr="lkg5">
+    <derivedVal>lkg</derivedVal>
+    <derivedSameVal>lkg</derivedSameVal>
+  </detail>
+</result>
diff --git a/tests/dynamic_function_call/test10.xsl b/tests/dynamic_function_call/test10.xsl
new file mode 100644
index 00000000..e678286d
--- /dev/null
+++ b/tests/dynamic_function_call/test10.xsl
@@ -0,0 +1,46 @@
+<?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_e.xml -->
+   
+   <!-- An XSLT stylesheet, to test the XPath 3.1 dynamic function 
+        call.-->                  
+
+   <xsl:output method="xml" indent="yes"/>
+   
+   <xsl:variable name="strTrimLastChar" select="function($str) { let $strLen := string-length($str) return 
+                                                                           substring($str, 1, $strLen - 1) }"/>
+
+   <xsl:template match="/temp">
+      <result>
+        <xsl:for-each select="a">
+          <detail origStr="{.}">
+             <derivedVal><xsl:value-of select="substring(., 1, string-length(.) - 1)"/></derivedVal>
+             <derivedSameVal><xsl:value-of select="$strTrimLastChar(string(.))"/></derivedSameVal>
+          </detail>
+        </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>
\ No newline at end of file
diff --git a/tests/dynamic_function_call/test1_e.xml b/tests/dynamic_function_call/test1_e.xml
new file mode 100644
index 00000000..17a12ae4
--- /dev/null
+++ b/tests/dynamic_function_call/test1_e.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<temp>
+  <a>abc1</a>
+  <a>pqr2</a>
+  <a>mno3</a>
+  <a>uvw4</a>
+  <a>lkg5</a>
+</temp>
+ 
\ 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 3785d0d6..c69a4974 100644
--- a/tests/org/apache/xalan/xpath3/DynamicFunctionCallTests.java
+++ b/tests/org/apache/xalan/xpath3/DynamicFunctionCallTests.java
@@ -136,5 +136,15 @@ public class DynamicFunctionCallTests extends XslTransformTestsUtil {
         
         runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
     }
+    
+    @Test
+    public void xslDynamicFunctionCallTest10() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_e.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test10.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test10.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
 
 }
diff --git a/tests/org/apache/xalan/xpath3/RangeExprTests.java b/tests/org/apache/xalan/xpath3/RangeExprTests.java
index 9302df3f..040b6062 100644
--- a/tests/org/apache/xalan/xpath3/RangeExprTests.java
+++ b/tests/org/apache/xalan/xpath3/RangeExprTests.java
@@ -169,5 +169,15 @@ public class RangeExprTests extends XslTransformTestsUtil {
         runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, 
                                                                        new XslTestsErrorHandler());
     }
+    
+    @Test
+    public void xslRangeExprTest13() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_c.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test13.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test13.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
 
 }
diff --git a/tests/org/apache/xalan/xpath3/DynamicFunctionCallTests.java b/tests/org/apache/xalan/xpath3/StringConcatExprTests.java
similarity index 60%
copy from tests/org/apache/xalan/xpath3/DynamicFunctionCallTests.java
copy to tests/org/apache/xalan/xpath3/StringConcatExprTests.java
index 3785d0d6..63eee479 100644
--- a/tests/org/apache/xalan/xpath3/DynamicFunctionCallTests.java
+++ b/tests/org/apache/xalan/xpath3/StringConcatExprTests.java
@@ -23,17 +23,18 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 
 /**
- * XPath 3.1 dynamic function call test cases.
+ * XPath 3.1 string concatenation operator, "||" test 
+ * cases.
  * 
  * @author Mukul Gandhi <mu...@apache.org>
  * 
  * @xsl.usage advanced
  */
-public class DynamicFunctionCallTests extends XslTransformTestsUtil {        
+public class StringConcatExprTests extends XslTransformTestsUtil {        
     
-    private static final String XSL_TRANSFORM_INPUT_DIRPATH = XSLConstants.XSL_TRANSFORM_INPUT_DIRPATH_PREFIX + "dynamic_function_call/";
+    private static final String XSL_TRANSFORM_INPUT_DIRPATH = XSLConstants.XSL_TRANSFORM_INPUT_DIRPATH_PREFIX + "stringConcatExpr/";
     
-    private static final String XSL_TRANSFORM_GOLD_DIRPATH = XSLConstants.XSL_TRANSFORM_GOLD_DIRPATH_PREFIX + "dynamic_function_call/gold/";
+    private static final String XSL_TRANSFORM_GOLD_DIRPATH = XSLConstants.XSL_TRANSFORM_GOLD_DIRPATH_PREFIX + "stringConcatExpr/gold/";
 
     @BeforeClass
     public static void setUpBeforeClass() throws Exception {
@@ -48,7 +49,7 @@ public class DynamicFunctionCallTests extends XslTransformTestsUtil {
     }
 
     @Test
-    public void xslDynamicFunctionCallTest1() {
+    public void xslStringConcatExprTest1() {
         String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl"; 
         String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl";
         
@@ -58,7 +59,7 @@ public class DynamicFunctionCallTests extends XslTransformTestsUtil {
     }
     
     @Test
-    public void xslDynamicFunctionCallTest2() {
+    public void xslStringConcatExprTest2() {
         String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml"; 
         String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.xsl";
         
@@ -68,7 +69,7 @@ public class DynamicFunctionCallTests extends XslTransformTestsUtil {
     }
     
     @Test
-    public void xslDynamicFunctionCallTest3() {
+    public void xslStringConcatExprTest3() {
         String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml"; 
         String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test3.xsl";
         
@@ -78,17 +79,17 @@ public class DynamicFunctionCallTests extends XslTransformTestsUtil {
     }
     
     @Test
-    public void xslDynamicFunctionCallTest4() {
+    public void xslStringConcatExprTest4() {
         String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml"; 
         String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test4.xsl";
         
-        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test3.out";                
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test4.out";                
         
         runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
     }
     
     @Test
-    public void xslDynamicFunctionCallTest5() {
+    public void xslStringConcatExprTest5() {
         String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_b.xml"; 
         String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test5.xsl";
         
@@ -96,45 +97,5 @@ public class DynamicFunctionCallTests extends XslTransformTestsUtil {
         
         runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
     }
-    
-    @Test
-    public void xslDynamicFunctionCallTest6() {
-        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_c.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 xslDynamicFunctionCallTest7() {
-        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_c.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 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);
-    }
-    
-    @Test
-    public void xslDynamicFunctionCallTest9() {
-        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_c.xml"; 
-        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test9.xsl";
-        
-        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test9.out";                
-        
-        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
-    }
 
 }
diff --git a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
index ee410e42..8587cbe0 100644
--- a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
+++ b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
@@ -34,6 +34,7 @@ import org.apache.xalan.xpath3.QuantifiedExprTests;
 import org.apache.xalan.xpath3.RangeExprTests;
 import org.apache.xalan.xpath3.SequenceConstructorTests;
 import org.apache.xalan.xpath3.SequenceTests;
+import org.apache.xalan.xpath3.StringConcatExprTests;
 import org.apache.xalan.xpath3.StringTests;
 import org.apache.xalan.xpath3.TrignometricAndExponentialFunctionTests;
 import org.apache.xalan.xpath3.ValueComparisonTests;
@@ -65,7 +66,7 @@ import org.junit.runners.Suite.SuiteClasses;
                 FnFilterTests.class, DynamicFunctionCallTests.class, IfExprTests.class, 
                 ForExprTests.class, LetExprTests.class, FnDistinctValuesTests.class,
                 TrignometricAndExponentialFunctionTests.class, BuiltinFunctionsNamespceTests.class,
-                SequenceConstructorTests.class })
+                SequenceConstructorTests.class, StringConcatExprTests.class })
 public class AllXsl3Tests {
 
 }
diff --git a/tests/range_expr/gold/test13.out b/tests/range_expr/gold/test13.out
new file mode 100644
index 00000000..8a4784a8
--- /dev/null
+++ b/tests/range_expr/gold/test13.out
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>1 2 3 4 5</one>
+  <two>1 2 3 4 5</two>
+  <three>1 2 3 4 5</three>
+  <four>1 2 3 4 5</four>
+  <five>1 2 3 4 5</five>
+  <six>1 2 3 4 5</six>
+</result>
diff --git a/tests/range_expr/test12.xsl b/tests/range_expr/test12.xsl
index 8e015de4..cfe48ee6 100644
--- a/tests/range_expr/test12.xsl
+++ b/tests/range_expr/test12.xsl
@@ -18,5 +18,23 @@
         </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>
\ No newline at end of file
diff --git a/tests/range_expr/test13.xsl b/tests/range_expr/test13.xsl
new file mode 100644
index 00000000..ef5e81b3
--- /dev/null
+++ b/tests/range_expr/test13.xsl
@@ -0,0 +1,43 @@
+<?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_c.xml -->
+   
+   <!-- An XSLT stylesheet test, to test the XPath 3.1 range
+        "to" operator. -->                
+
+   <xsl:output method="xml" indent="yes"/>
+
+   <xsl:template match="/temp">
+      <result>
+        <one><xsl:value-of select="1 to 5"/></one>
+        <two><xsl:copy-of select="1 to 5"/></two>
+        <three><xsl:value-of select="a to b"/></three>
+        <four><xsl:copy-of select="a to b"/></four>
+        <five><xsl:value-of select="c/@from to c/@to"/></five>
+        <six><xsl:copy-of select="c/@from to c/@to"/></six>
+      </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/range_expr/test1_c.xml b/tests/range_expr/test1_c.xml
new file mode 100644
index 00000000..282a0171
--- /dev/null
+++ b/tests/range_expr/test1_c.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<temp>
+  <a>1</a>
+  <b>5</b>
+  <c from="1" to="5"/>
+</temp>
+ 
\ No newline at end of file
diff --git a/tests/stringConcatExpr/gold/test1.out b/tests/stringConcatExpr/gold/test1.out
new file mode 100644
index 00000000..20601ad2
--- /dev/null
+++ b/tests/stringConcatExpr/gold/test1.out
@@ -0,0 +1 @@
+concatenate
\ No newline at end of file
diff --git a/tests/stringConcatExpr/gold/test2.out b/tests/stringConcatExpr/gold/test2.out
new file mode 100644
index 00000000..11c65a06
--- /dev/null
+++ b/tests/stringConcatExpr/gold/test2.out
@@ -0,0 +1 @@
+123 hello world
\ No newline at end of file
diff --git a/tests/stringConcatExpr/gold/test3.out b/tests/stringConcatExpr/gold/test3.out
new file mode 100644
index 00000000..b6fc4c62
--- /dev/null
+++ b/tests/stringConcatExpr/gold/test3.out
@@ -0,0 +1 @@
+hello
\ No newline at end of file
diff --git a/tests/stringConcatExpr/gold/test4.out b/tests/stringConcatExpr/gold/test4.out
new file mode 100644
index 00000000..9ce14c03
--- /dev/null
+++ b/tests/stringConcatExpr/gold/test4.out
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>hello</one>
+  <two>world</two>
+</result>
diff --git a/tests/stringConcatExpr/gold/test5.out b/tests/stringConcatExpr/gold/test5.out
new file mode 100644
index 00000000..879805af
--- /dev/null
+++ b/tests/stringConcatExpr/gold/test5.out
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>abc pqr</one>
+  <two>
+    <a>abc</a>
+    <b>pqr</b>
+  </two>
+</result>
diff --git a/tests/stringConcatExpr/test1.xsl b/tests/stringConcatExpr/test1.xsl
new file mode 100644
index 00000000..f1f29426
--- /dev/null
+++ b/tests/stringConcatExpr/test1.xsl
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="3.0">
+                
+   <!-- Author: mukulg@apache.org -->
+   
+   <!-- An XSLT stylesheet test, to test XPath 3.1 string
+        concatenation operator "||".
+        
+        An XPath string concatenation expression, illustrated
+        within this stylesheet example, is borrowed from XPath 3.1
+        spec. -->                
+
+   <xsl:output method="text"/>
+
+   <xsl:template match="/">
+      <xsl:value-of select="'con' || 'cat' || 'enate'"/>
+   </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/stringConcatExpr/test1_a.xml b/tests/stringConcatExpr/test1_a.xml
new file mode 100644
index 00000000..7f0c3b9a
--- /dev/null
+++ b/tests/stringConcatExpr/test1_a.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<temp val="123">
+  <a>hello</a>
+  <b>world</b>
+</temp>
+ 
\ No newline at end of file
diff --git a/tests/stringConcatExpr/test1_b.xml b/tests/stringConcatExpr/test1_b.xml
new file mode 100644
index 00000000..e7251a08
--- /dev/null
+++ b/tests/stringConcatExpr/test1_b.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<temp>
+  <a>abc</a>
+  <b>pqr</b>
+</temp>
+ 
\ No newline at end of file
diff --git a/tests/stringConcatExpr/test2.xsl b/tests/stringConcatExpr/test2.xsl
new file mode 100644
index 00000000..feb5d760
--- /dev/null
+++ b/tests/stringConcatExpr/test2.xsl
@@ -0,0 +1,36 @@
+<?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_a.xml -->
+   
+   <!-- An XSLT stylesheet test, to test XPath 3.1 string
+        concatenation operator "||". -->                 
+
+   <xsl:output method="text"/>
+
+   <xsl:template match="/temp">
+      <xsl:value-of select="@val || ' ' || a || ' ' || b"/>
+   </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/stringConcatExpr/test3.xsl b/tests/stringConcatExpr/test3.xsl
new file mode 100644
index 00000000..45e75a7e
--- /dev/null
+++ b/tests/stringConcatExpr/test3.xsl
@@ -0,0 +1,39 @@
+<?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_a.xml -->
+   
+   <!-- An XSLT stylesheet test, to test XPath 3.1 string
+        concatenation operator "||".
+        
+        This stylesheet, emits the string value of XML element 
+        "a", when the condition within the predicate is true. -->                
+
+   <xsl:output method="text"/>
+
+   <xsl:template match="/temp">      
+      <xsl:value-of select="a[(../@val || ' ' || ../b) eq '123 world']"/>
+   </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/stringConcatExpr/test4.xsl b/tests/stringConcatExpr/test4.xsl
new file mode 100644
index 00000000..7ddd32d9
--- /dev/null
+++ b/tests/stringConcatExpr/test4.xsl
@@ -0,0 +1,39 @@
+<?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_a.xml -->
+   
+   <!-- An XSLT stylesheet test, to test XPath 3.1 string
+        concatenation operator "||". -->                  
+
+   <xsl:output method="xml" indent="yes"/>
+
+   <xsl:template match="/temp">
+      <result>
+         <one><xsl:value-of select="if ((@val || ' ' || b) eq '123 world') then a else b"/></one>
+         <two><xsl:value-of select="if (not((@val || ' ' || b) eq '123 world')) then a else b"/></two>
+      </result>
+   </xsl:template>
+   
+   <!--
+      * Licensed to the Apache Software Foundation (ASF) under one
+      * or more contributor license agreements. See the NOTICE file
+      * distributed with this work for additional information
+      * regarding copyright ownership. The ASF licenses this file
+      * to you under the Apache License, Version 2.0 (the  "License");
+      * you may not use this file except in compliance with the License.
+      * You may obtain a copy of the License at
+      *
+      *     http://www.apache.org/licenses/LICENSE-2.0
+      *
+      * Unless required by applicable law or agreed to in writing, software
+      * distributed under the License is distributed on an "AS IS" BASIS,
+      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      * See the License for the specific language governing permissions and
+      * limitations under the License.
+   -->
+
+</xsl:stylesheet>
\ No newline at end of file
diff --git a/tests/stringConcatExpr/test5.xsl b/tests/stringConcatExpr/test5.xsl
new file mode 100644
index 00000000..5272a79c
--- /dev/null
+++ b/tests/stringConcatExpr/test5.xsl
@@ -0,0 +1,55 @@
+<?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_b.xml -->
+   
+   <!-- An XSLT stylesheet test, to test the XPath union operator
+        '|'. Since the XPath operator string '|' seems syntactically 
+        similar to the XPath operator string '||' (an XPath string 
+        concatenation operator), we test via this XSLT stylesheet, 
+        the XPath operator '|'.
+        
+        Also, as per XSLT 3.0 spec, different behavior applies when the 
+        "xsl:value-of" instruction is processed with XSLT 1.0 processor. 
+        If no separator attribute is present on "xsl:value-of" instruction, 
+        and if the select attribute is present, then all items in the 
+        atomized result sequence other than the first are ignored. We also,
+        test this "xsl:value-of" instruction functionality change, within
+        this XSLT stylesheet. 
+   -->            
+
+   <xsl:output method="xml" indent="yes"/>
+
+   <xsl:template match="/temp">
+      <result>
+         <one>
+            <xsl:value-of select="a | b"/>
+         </one>
+         <two>
+	        <xsl:copy-of select="a | b"/>
+         </two>
+      </result>
+   </xsl:template>
+   
+   <!--
+      * Licensed to the Apache Software Foundation (ASF) under one
+      * or more contributor license agreements. See the NOTICE file
+      * distributed with this work for additional information
+      * regarding copyright ownership. The ASF licenses this file
+      * to you under the Apache License, Version 2.0 (the  "License");
+      * you may not use this file except in compliance with the License.
+      * You may obtain a copy of the License at
+      *
+      *     http://www.apache.org/licenses/LICENSE-2.0
+      *
+      * Unless required by applicable law or agreed to in writing, software
+      * distributed under the License is distributed on an "AS IS" BASIS,
+      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      * See the License for the specific language governing permissions and
+      * limitations under the License.
+   -->
+
+</xsl:stylesheet>
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xalan.apache.org
For additional commands, e-mail: commits-help@xalan.apache.org