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/06/06 10:09:45 UTC

[xalan-java] branch xalan-j_xslt3.0 updated: committing implementation of xpath 3.1 fn:index-of method. minor improvements to xsl:analyze-string instruction's implementation. other miscellaneous xalanj codebase minor improvements. adding few new working xslt 3.0 and xpath 3.1 test cases 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 8abfe6e0 committing implementation of xpath 3.1 fn:index-of method. minor improvements to xsl:analyze-string instruction's implementation. other miscellaneous xalanj codebase minor improvements. adding few new working xslt 3.0 and xpath 3.1 test cases as well.
8abfe6e0 is described below

commit 8abfe6e0781e65bb6b704d4d51ef6eaf1d778315
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Tue Jun 6 15:39:21 2023 +0530

    committing implementation of xpath 3.1 fn:index-of method. minor improvements to xsl:analyze-string instruction's implementation. other miscellaneous xalanj codebase minor improvements. adding few new working xslt 3.0 and xpath 3.1 test cases as well.
---
 .../apache/xalan/templates/ElemAnalyzeString.java  |  37 +++++--
 .../xalan/templates/ElemMatchingSubstring.java     |   3 +-
 .../xalan/templates/ElemNonMatchingSubstring.java  |   3 +-
 src/org/apache/xml/dtm/DTMManager.java             |  46 ++++----
 src/org/apache/xpath/XPathContext.java             |   2 +-
 src/org/apache/xpath/compiler/FunctionTable.java   |   9 +-
 src/org/apache/xpath/compiler/Keywords.java        |   4 +
 src/org/apache/xpath/functions/FuncCount.java      |  10 ++
 src/org/apache/xpath/functions/FuncIndexOf.java    | 120 +++++++++++++++++++++
 src/org/apache/xpath/objects/ResultSequence.java   |  47 +++++++-
 tests/analyze_string/gold/test12.out               |   1 +
 tests/analyze_string/gold/test13.out               |   9 ++
 tests/analyze_string/test12.xsl                    |  56 ++++++++++
 tests/analyze_string/test13.xsl                    |  63 +++++++++++
 tests/analyze_string/test1_h.xml                   |  10 ++
 tests/fn_indexof/gold/test1.out                    |   4 +
 tests/fn_indexof/test1.xsl                         |  37 +++++++
 tests/fn_tokenize/gold/test11.out                  |   2 +
 tests/fn_tokenize/gold/test12.out                  |   1 +
 tests/fn_tokenize/test11.xsl                       |  36 +++++++
 tests/fn_tokenize/test12.xsl                       |  35 ++++++
 tests/org/apache/xalan/xpath3/FnAbsTests.java      |   2 +-
 .../{FnAbsTests.java => FnIndexOfTests.java}       |  12 +--
 .../org/apache/xalan/xpath3/FnStringJoinTests.java |   2 +-
 tests/org/apache/xalan/xpath3/FnTokenizeTests.java |  22 +++-
 .../apache/xalan/xpath3/FnUnparsedTextTests.java   |   2 +-
 tests/org/apache/xalan/xslt3/AllXsl3Tests.java     |   4 +-
 .../org/apache/xalan/xslt3/AnalyzeStringTests.java |  20 ++++
 28 files changed, 549 insertions(+), 50 deletions(-)

diff --git a/src/org/apache/xalan/templates/ElemAnalyzeString.java b/src/org/apache/xalan/templates/ElemAnalyzeString.java
index 1d6d8bfa..f7bfc5aa 100644
--- a/src/org/apache/xalan/templates/ElemAnalyzeString.java
+++ b/src/org/apache/xalan/templates/ElemAnalyzeString.java
@@ -67,10 +67,9 @@ import org.apache.xpath.regex.Matcher;
  * The XSLT function fn:regex-group may be used optionally, along with XSLT instruction 
  * xsl:analyze-string.
  * 
- * With xsl:analyze-string element, we're presently not implementing xsl:fallback 
+ * With xsl:analyze-string element, we've presently not implemented xsl:fallback 
  * elements. xsl:fallback elements don't seem to have much useful use cases within 
- * xsl:analyze-string element.   // revisit 
- * 
+ * xsl:analyze-string element.   // revisit
  */
 public class ElemAnalyzeString extends ElemTemplateElement implements ExpressionOwner {
   
@@ -284,13 +283,30 @@ public class ElemAnalyzeString extends ElemTemplateElement implements Expression
            strToBeAnalyzedMatchingSubsequences.add(str);
        }
        
-       // we use a fairly random string like the string value of 'System.currentTimeMillis()',
-       // to help us pre-process the input string to be analyzed. 
+       // we use the string value of 'System.currentTimeMillis()' representing
+       // a fairly random string, to help us pre-process the input string 
+       // that is been analyzed by xsl:analyze-string instruction. 
        long currentTimeMills = System.currentTimeMillis();
-       String tempReplStr = (Long.valueOf(currentTimeMills)).toString();
-       String tempReplacedStr = regexMatcher.replaceAll(tempReplStr);
+       String str1 = (Long.valueOf(currentTimeMills)).toString();
+       String str1Replaced = regexMatcher.replaceAll(str1);
+       
+       if (str1Replaced.equals(str1)) {
+          // handle the case, where xsl:analyze-string's regex matches 
+          // the whole of the input string. 
+          if ((templateElem1 != null) && (templateElem1 instanceof ElemMatchingSubstring)) {
+              ((ElemMatchingSubstring)templateElem1).setStrValue(strToBeAnalyzed);
+              ((ElemMatchingSubstring)templateElem1).setRegex(effectiveRegexStrValue);
+              ((ElemMatchingSubstring)templateElem1).setFlags(m_regex_flags);
+              xctxt.setSAXLocator(templateElem1);
+              transformer.setCurrentElement(templateElem1);                   
+              templateElem1.execute(transformer);   
+          }
+          
+          return;
+       }
+       
+       String[] strParts = str1Replaced.split(str1);
        
-       String[] strParts = tempReplacedStr.split(tempReplStr);
        int i2 = 0;
        for (int idx = 0; idx < strParts.length; idx++) {           
            if (templateElem2 != null) {
@@ -309,7 +325,7 @@ public class ElemAnalyzeString extends ElemTemplateElement implements Expression
                }
                else {
                    if ((idx < strParts.length - 1) || ((idx == strParts.length - 1) && 
-                                                                 tempReplacedStr.endsWith(tempReplStr))) {
+                                                                 str1Replaced.endsWith(str1))) {
                       ((ElemMatchingSubstring)templateElem1).setStrValue(
                                                                  strToBeAnalyzedMatchingSubsequences.get(i2));
                       ((ElemMatchingSubstring)templateElem1).setRegex(effectiveRegexStrValue);
@@ -321,8 +337,7 @@ public class ElemAnalyzeString extends ElemTemplateElement implements Expression
                    }
                }
            }
-       }
-       
+       }       
   }
 
   /**
diff --git a/src/org/apache/xalan/templates/ElemMatchingSubstring.java b/src/org/apache/xalan/templates/ElemMatchingSubstring.java
index 3156933d..3a61891a 100644
--- a/src/org/apache/xalan/templates/ElemMatchingSubstring.java
+++ b/src/org/apache/xalan/templates/ElemMatchingSubstring.java
@@ -48,7 +48,6 @@ import org.apache.xpath.XPathContext;
  * Implementation of the XSLT 3.0 xsl:matching-substring instruction.
  * 
  * This XSLT element can only be used within the element xsl:analyze-string.
- * 
  */
 public class ElemMatchingSubstring extends ElemTemplateElement implements ExpressionOwner {
   
@@ -148,6 +147,8 @@ public class ElemMatchingSubstring extends ElemTemplateElement implements Expres
       customDataMap.put(REGEX_FLAGS, m_flags);
       
       XPathContext xctxtNew = new XPathContext(false);
+      
+      xctxtNew.setVarStack(xctxt.getVarStack());
 
       DTMManager dtmMgr = xctxtNew.getDTMManager();      
       DTM docFragDtm = dtmMgr.createDTMForSimpleXMLDocument(strValueTobeEvaluated);
diff --git a/src/org/apache/xalan/templates/ElemNonMatchingSubstring.java b/src/org/apache/xalan/templates/ElemNonMatchingSubstring.java
index 7a810e31..7dc13752 100644
--- a/src/org/apache/xalan/templates/ElemNonMatchingSubstring.java
+++ b/src/org/apache/xalan/templates/ElemNonMatchingSubstring.java
@@ -45,7 +45,6 @@ import org.apache.xpath.XPathContext;
  * Implementation of the XSLT 3.0 xsl:non-matching-substring instruction.
  * 
  * This XSLT element can only be used within the element xsl:analyze-string.
- * 
  */
 public class ElemNonMatchingSubstring extends ElemTemplateElement implements ExpressionOwner {
 
@@ -131,6 +130,8 @@ public class ElemNonMatchingSubstring extends ElemTemplateElement implements Exp
       String strValueTobeEvaluated = getStrValue();
       
       XPathContext xctxtNew = new XPathContext(false);
+      
+      xctxtNew.setVarStack(xctxt.getVarStack());
 
       DTMManager dtmMgr = xctxtNew.getDTMManager();      
       DTM docFragDtm = dtmMgr.createDTMForSimpleXMLDocument(strValueTobeEvaluated);
diff --git a/src/org/apache/xml/dtm/DTMManager.java b/src/org/apache/xml/dtm/DTMManager.java
index 771cf387..b8a149c9 100644
--- a/src/org/apache/xml/dtm/DTMManager.java
+++ b/src/org/apache/xml/dtm/DTMManager.java
@@ -49,8 +49,6 @@ import org.w3c.dom.Text;
  * <p>Note: this class is incomplete right now.  It will be pretty much
  * modeled after javax.xml.transform.TransformerFactory in terms of its
  * factory support.</p>
- *
- * <p>State: In progress!!</p>
  */
 public abstract class DTMManager
 {
@@ -217,30 +215,40 @@ public abstract class DTMManager
   public abstract DTM createDocumentFragment();
   
   /*
-   * This method has been defined, to construct a DTM object, representing an
-   * XML document that contains only 'one xml element with a text node child'.
-   * This method currently supports, evaluation of XSLT xsl:analyze-string 
-   * instruction.
+   * This method constructs a DTM object representing an XML document. 
+   * The DTM instance that is constructed by this method, contains only 
+   * 'one xml element with a text node child'. This method currently 
+   * supports, evaluation of XSLT xsl:analyze-string instruction.
+   * 
+   * @param strVal   string value of the text node, that shall be available
+   *                 within this constructed DTM object.
+   *                 
+   * @return         the DTM object, that is constructed by this method         
+   *    
    */
   public DTM createDTMForSimpleXMLDocument(String strVal) {    
         try {
-          DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+           DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
     
-          dbf.setNamespaceAware(true);
+           dbf.setNamespaceAware(true);
     
-          DocumentBuilder db = dbf.newDocumentBuilder();
-          Document doc = db.newDocument();
-          // "temp" is an arbitrary name selected for an XML element,
-          // for this purpose.
-          Element elem = doc.createElement("temp");
-          Text textNode = doc.createTextNode(strVal);
-          elem.appendChild(textNode);
-          doc.appendChild(elem);
+           DocumentBuilder db = dbf.newDocumentBuilder();
+           Document doc = db.newDocument();
+           // we create a, temporary xml element name here. this xml 
+           // element name, is unlikely to be present within the xml 
+           // input document that is been transformed by an xslt 
+           // stylesheet.
+           long currentTimeMills = System.currentTimeMillis();
+           String elemNameSuffix = (Long.valueOf(currentTimeMills)).toString();
+           Element elem = doc.createElement("t0_" + elemNameSuffix);
+           Text textNode = doc.createTextNode(strVal);
+           elem.appendChild(textNode);
+           doc.appendChild(elem);
     
-          return getDTM(new DOMSource(doc), true, null, false, false);
+           return getDTM(new DOMSource(doc), true, null, false, false);
         }
-        catch (Exception e) {
-            throw new DTMException(e);
+        catch (Exception ex) {
+           throw new DTMException(ex);
         }
   }
 
diff --git a/src/org/apache/xpath/XPathContext.java b/src/org/apache/xpath/XPathContext.java
index 68bcddc2..2ca48c88 100644
--- a/src/org/apache/xpath/XPathContext.java
+++ b/src/org/apache/xpath/XPathContext.java
@@ -503,7 +503,7 @@ public class XPathContext extends DTMManager // implements ExpressionContext
   }
 
   /** 
-   * Get the variable stack, which is in charge of variables and
+   * Set the variable stack, which is in charge of variables and
    * parameters.
    *
    * @param varStack non-null reference to the variable stack.
diff --git a/src/org/apache/xpath/compiler/FunctionTable.java b/src/org/apache/xpath/compiler/FunctionTable.java
index 056a9bf7..e0101823 100644
--- a/src/org/apache/xpath/compiler/FunctionTable.java
+++ b/src/org/apache/xpath/compiler/FunctionTable.java
@@ -176,6 +176,9 @@ public class FunctionTable
   
   /** The 'implicit-timezone()' id. */
   public static final int FUNC_IMPLICIT_TIMEZONE = 51;
+  
+  /** The 'index-of()' id. */
+  public static final int FUNC_INDEX_OF = 52;
 
   // Proprietary
 
@@ -204,7 +207,7 @@ public class FunctionTable
    * Number of built in functions. Be sure to update this as
    * built-in functions are added.
    */
-  private static final int NUM_BUILT_IN_FUNCS = 52;
+  private static final int NUM_BUILT_IN_FUNCS = 53;
 
   /**
    * Number of built-in functions that may be added.
@@ -300,6 +303,8 @@ public class FunctionTable
       org.apache.xpath.functions.FuncLowerCase.class;
     m_functions[FUNC_IMPLICIT_TIMEZONE] = 
       org.apache.xpath.functions.FuncImplicitTimezone.class;
+    m_functions[FUNC_INDEX_OF] = 
+      org.apache.xpath.functions.FuncIndexOf.class;
   }
 
   static{
@@ -403,6 +408,8 @@ public class FunctionTable
                           new Integer(FunctionTable.FUNC_LOWER_CASE));
           m_functionID.put(Keywords.FUNC_IMPLICIT_TIMEZONE,
                           new Integer(FunctionTable.FUNC_IMPLICIT_TIMEZONE));
+          m_functionID.put(Keywords.FUNC_INDEX_OF,
+                          new Integer(FunctionTable.FUNC_INDEX_OF));
   }
   
   public FunctionTable(){
diff --git a/src/org/apache/xpath/compiler/Keywords.java b/src/org/apache/xpath/compiler/Keywords.java
index fceac675..a5f4f4a3 100644
--- a/src/org/apache/xpath/compiler/Keywords.java
+++ b/src/org/apache/xpath/compiler/Keywords.java
@@ -24,6 +24,7 @@ import java.util.Hashtable;
 
 /**
  * Table of strings to operation code lookups.
+ * 
  * @xsl.usage internal
  */
 public class Keywords
@@ -255,6 +256,9 @@ public class Keywords
   
   /** implicit-timezone function string. */
   public static final String FUNC_IMPLICIT_TIMEZONE = "implicit-timezone";
+  
+  /** index-of function string. */
+  public static final String FUNC_INDEX_OF = "index-of";
 
   // Proprietary, built in functions
 
diff --git a/src/org/apache/xpath/functions/FuncCount.java b/src/org/apache/xpath/functions/FuncCount.java
index ff682026..3ca8f438 100644
--- a/src/org/apache/xpath/functions/FuncCount.java
+++ b/src/org/apache/xpath/functions/FuncCount.java
@@ -27,6 +27,7 @@ import org.apache.xpath.objects.ResultSequence;
 import org.apache.xpath.objects.XNodeSet;
 import org.apache.xpath.objects.XNumber;
 import org.apache.xpath.objects.XObject;
+import org.apache.xpath.operations.Variable;
 
 /**
  * Execute the count() function.
@@ -58,6 +59,15 @@ public class FuncCount extends FunctionOneArg
                count = ((ResultSequence)evalResult).size();
             }
         }
+        else if (m_arg0 instanceof Variable) {
+           XObject evalResult = ((Variable)m_arg0).execute(xctxt);
+           if (evalResult instanceof XNodeSet) {
+               count = ((XNodeSet)evalResult).getLength();   
+           }
+           else if (evalResult instanceof ResultSequence) {
+              count = ((ResultSequence)evalResult).size();
+           }
+        }
         else if (m_arg0 instanceof Expression) {
             DTMIterator nl = m_arg0.asIterator(xctxt, xctxt.getCurrentNode());
             count = nl.getLength();	
diff --git a/src/org/apache/xpath/functions/FuncIndexOf.java b/src/org/apache/xpath/functions/FuncIndexOf.java
new file mode 100644
index 00000000..67a5cbba
--- /dev/null
+++ b/src/org/apache/xpath/functions/FuncIndexOf.java
@@ -0,0 +1,120 @@
+/*
+ * 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.functions;
+
+import java.math.BigInteger;
+
+import javax.xml.transform.SourceLocator;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xpath.Expression;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.ResultSequence;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.res.XPATHErrorResources;
+import org.apache.xpath.xs.types.XSInteger;
+
+/**
+ * Execute the index-of() function.
+ * 
+ * This function, returns a sequence of positive integers giving the positions 
+ * within the sequence $seq of items that are equal to $search.
+ * 
+ * Function signatures :
+ *      1) fn:index-of($seq         as xs:anyAtomicType*,
+                       $search      as xs:anyAtomicType) as xs:integer*
+
+        2) fn:index-of($seq         as xs:anyAtomicType*,
+                       $search      as xs:anyAtomicType,
+                       $collation   as xs:string) as xs:integer*
+ *
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class FuncIndexOf extends Function3Args {
+
+   private static final long serialVersionUID = 2912594883291006421L;
+   
+   private static final String FUNCTION_NAME = "index-of()"; 
+
+  /**
+   * Execute the function. The function must return a valid object.
+   * 
+   * @param xctxt The current execution context.
+   * 
+   * @return A valid XObject.
+   *
+   * @throws javax.xml.transform.TransformerException
+   */
+  public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
+  {      
+        SourceLocator srcLocator = xctxt.getSAXLocator();
+        
+        ResultSequence resultSeq = new ResultSequence();
+        
+        Expression arg0 = getArg0();
+        Expression arg1 = getArg1();
+        
+        XObject arg0Obj = arg0.execute(xctxt);
+
+        if (!(arg0Obj instanceof ResultSequence)) {
+           throw new javax.xml.transform.TransformerException("The first argument of fn:index-of is "
+                                                                      + "not a sequence.", srcLocator);     
+        }
+        
+        XObject arg1Obj = arg1.execute(xctxt);
+        
+        ResultSequence arg0ResultSeq = (ResultSequence)arg0Obj;
+        
+        for (int idx = 0; idx < arg0ResultSeq.size(); idx++) {
+           if ((arg0ResultSeq.item(idx)).equals(arg1Obj)) {
+              resultSeq.add(new XSInteger(BigInteger.valueOf(idx + 1)));    
+           }
+        }
+            
+        return resultSeq;
+  }
+
+  /**
+   * Check that the number of arguments passed to this function is correct.
+   *
+   * @param argNum The number of arguments that is being passed to the function.
+   *
+   * @throws WrongNumberArgsException
+   */
+  public void checkNumberArgs(int argNum) throws WrongNumberArgsException
+  {
+     if (!(argNum == 2 || argNum == 3)) {
+        reportWrongNumberArgs();
+     }
+  }
+
+  /**
+   * Constructs and throws a WrongNumberArgException with the appropriate
+   * message for this function object.
+   *
+   * @throws WrongNumberArgsException
+   */
+  protected void reportWrongNumberArgs() throws WrongNumberArgsException {
+      throw new WrongNumberArgsException(XSLMessages.createXPATHMessage(
+                                              XPATHErrorResources.ER_TWO_OR_THREE, null)); //"2 or 3"
+  }
+
+}
diff --git a/src/org/apache/xpath/objects/ResultSequence.java b/src/org/apache/xpath/objects/ResultSequence.java
index b22cff3f..ab4a8c4f 100644
--- a/src/org/apache/xpath/objects/ResultSequence.java
+++ b/src/org/apache/xpath/objects/ResultSequence.java
@@ -15,16 +15,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/*
- * $Id$
- */
 package org.apache.xpath.objects;
 
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.xpath.xs.types.XSAnyType;
+
 /**
- * This class represents, an object for XPath 3.1 data model sequences.
+ * This class represents, the XPath 3.1 data model sequences.
  * 
  * @author Mukul Gandhi <mu...@apache.org>
  * 
@@ -37,7 +36,9 @@ public class ResultSequence extends XObject
     // the underlying list object, storing items of this result sequence 
     private List<XObject> rsList = new ArrayList<XObject>();
     
-    // Class constructor.
+    /*
+     * Class constructor.
+     */
     public ResultSequence() {}
     
     public void add(XObject item) {
@@ -55,5 +56,41 @@ public class ResultSequence extends XObject
     public List<XObject> getResultSequenceItems() {
         return rsList;   
     }
+    
+    /*
+     * Get the string value of this ResultSequence object.
+     * 
+     * This method, produces a default serialization of this
+     * string value, which is space separated string values 
+     * of the xdm items of this sequence.
+     */
+    public String str() {
+        String resultStr = null;
+        
+        StringBuffer strBuff = new StringBuffer();
+        for (int idx = 0; idx < rsList.size(); idx++) {
+           XObject item = rsList.get(idx);
+           if (idx < (rsList.size() - 1)) {
+              if (item instanceof XSAnyType) {
+                  strBuff.append(((XSAnyType)item).stringValue() + " ");    
+              }
+              else {
+                 strBuff.append((rsList.get(idx)).str() + " ");
+              }
+           }
+           else {
+              if (item instanceof XSAnyType) {
+                  strBuff.append(((XSAnyType)item).stringValue());     
+              }
+              else {
+                 strBuff.append((rsList.get(idx)).str());
+              }
+           }
+        }
+        
+        resultStr = strBuff.toString(); 
+        
+        return resultStr;
+    }
 
 }
diff --git a/tests/analyze_string/gold/test12.out b/tests/analyze_string/gold/test12.out
new file mode 100644
index 00000000..3cfc8483
--- /dev/null
+++ b/tests/analyze_string/gold/test12.out
@@ -0,0 +1 @@
+2002-03-23
\ No newline at end of file
diff --git a/tests/analyze_string/gold/test13.out b/tests/analyze_string/gold/test13.out
new file mode 100644
index 00000000..9f786111
--- /dev/null
+++ b/tests/analyze_string/gold/test13.out
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <date>2002-01-05</date>
+  <date>2003-02-06</date>
+  <date>2004-03-07</date>
+  <date>2005-04-08</date>
+  <date>2006-05-02</date>
+  <date>2006-11-03</date>
+  <date>2006-12-04</date>
+</result>
diff --git a/tests/analyze_string/test12.xsl b/tests/analyze_string/test12.xsl
new file mode 100644
index 00000000..3294cb2c
--- /dev/null
+++ b/tests/analyze_string/test12.xsl
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="3.0">
+                
+   <!-- Author: mukulg@apache.org -->
+   
+   <!-- XSLT stylesheet to transform, date with string format '23 March 2002' 
+        to the string format '2002-03-23'. -->
+
+   <xsl:output method="text"/>
+     
+   <xsl:variable name="months" select="tokenize('January February March April May June July August September October November December','\s+')"/>
+   
+   <xsl:variable name="date1" select="'23 March 2002'"/>
+
+   <xsl:template match="/">      
+      <xsl:analyze-string select="$date1" regex="([0-9]{{1,2}})\s([A-Z][a-z]+)\s([0-9]{{4}})">          
+          <xsl:matching-substring>              
+              <xsl:value-of select="regex-group(3)"/>
+              <xsl:text>-</xsl:text>
+              <xsl:variable name="monthNum">
+                 <xsl:value-of select="index-of($months, regex-group(2))"/>
+              </xsl:variable>
+              <xsl:choose>
+                 <xsl:when test="$monthNum &lt; 10">
+                    <xsl:value-of select="concat('0',$monthNum)"/>
+                 </xsl:when>
+                 <xsl:otherwise>
+                    <xsl:value-of select="$monthNum"/>
+                 </xsl:otherwise>
+              </xsl:choose>
+              <xsl:text>-</xsl:text>
+              <xsl:value-of select="regex-group(1)"/>
+          </xsl:matching-substring>
+      </xsl:analyze-string>
+   </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/analyze_string/test13.xsl b/tests/analyze_string/test13.xsl
new file mode 100644
index 00000000..099292ac
--- /dev/null
+++ b/tests/analyze_string/test13.xsl
@@ -0,0 +1,63 @@
+<?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_h.xml -->
+   
+   <!-- XSLT stylesheet to transform, date with string format '23 March 2002' 
+        to the string format '2002-03-23'. This stylesheet, transforms sequence 
+        of xml 'date' elements. -->
+
+   <xsl:output method="xml" indent="yes"/>
+     
+   <xsl:variable name="months" select="tokenize('January February March April May June July August September October November December','\s+')"/>
+
+   <xsl:template match="/elem">
+      <result>
+         <xsl:for-each select="date">
+             <date>      
+                 <xsl:analyze-string select="." regex="([0-9]{{1,2}})\s([A-Z][a-z]+)\s([0-9]{{4}})">          
+                     <xsl:matching-substring>              
+                         <xsl:value-of select="regex-group(3)"/>
+                         <xsl:text>-</xsl:text>
+                         <xsl:variable name="monthNum">
+                            <xsl:value-of select="index-of($months, regex-group(2))"/>
+                         </xsl:variable>
+                         <xsl:choose>
+                            <xsl:when test="$monthNum &lt; 10">
+                               <xsl:value-of select="concat('0',$monthNum)"/>
+                            </xsl:when>
+                            <xsl:otherwise>
+                               <xsl:value-of select="$monthNum"/>
+                            </xsl:otherwise>
+                         </xsl:choose>
+                         <xsl:text>-</xsl:text>
+                         <xsl:value-of select="regex-group(1)"/>
+                     </xsl:matching-substring>
+                 </xsl:analyze-string>
+             </date>
+         </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/analyze_string/test1_h.xml b/tests/analyze_string/test1_h.xml
new file mode 100644
index 00000000..195a0ff1
--- /dev/null
+++ b/tests/analyze_string/test1_h.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<elem>
+  <date>05 January 2002</date>
+  <date>06 February 2003</date>
+  <date>07 March 2004</date>
+  <date>08 April 2005</date>
+  <date>02 May 2006</date>
+  <date>03 November 2006</date>
+  <date>04 December 2006</date>
+</elem>
\ No newline at end of file
diff --git a/tests/fn_indexof/gold/test1.out b/tests/fn_indexof/gold/test1.out
new file mode 100644
index 00000000..6ad38795
--- /dev/null
+++ b/tests/fn_indexof/gold/test1.out
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>2 3. size : 2</one>
+  <two>4 6 7. size : 3</two>
+</result>
diff --git a/tests/fn_indexof/test1.xsl b/tests/fn_indexof/test1.xsl
new file mode 100644
index 00000000..41cf5a2c
--- /dev/null
+++ b/tests/fn_indexof/test1.xsl
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="3.0">
+                
+   <!-- Author: mukulg@apache.org -->
+   
+   <!-- test for the XPath 3.1 fn:index-of() function -->
+
+   <xsl:output method="xml" indent="yes"/>
+
+   <xsl:template match="/">
+      <xsl:variable name="words" select="tokenize('a abc abc pqr mno pqr pqr','\s+')"/>
+      <result>
+         <one><xsl:value-of select="index-of($words, 'abc')"/>. size : <xsl:value-of select="count(index-of($words, 'abc'))"/></one>
+         <two><xsl:value-of select="index-of($words, 'pqr')"/>. size : <xsl:value-of select="count(index-of($words, 'pqr'))"/></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/fn_tokenize/gold/test11.out b/tests/fn_tokenize/gold/test11.out
new file mode 100644
index 00000000..a2172334
--- /dev/null
+++ b/tests/fn_tokenize/gold/test11.out
@@ -0,0 +1,2 @@
+a b c d
+a b c d
\ No newline at end of file
diff --git a/tests/fn_tokenize/gold/test12.out b/tests/fn_tokenize/gold/test12.out
new file mode 100644
index 00000000..ff852910
--- /dev/null
+++ b/tests/fn_tokenize/gold/test12.out
@@ -0,0 +1 @@
+a b c d
\ No newline at end of file
diff --git a/tests/fn_tokenize/test11.xsl b/tests/fn_tokenize/test11.xsl
new file mode 100644
index 00000000..a430f775
--- /dev/null
+++ b/tests/fn_tokenize/test11.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 -->
+   
+   <!-- testing the default, xslt serialization of an XDM sequence,
+        with xsl:value-of instruction. -->
+
+   <xsl:output method="text"/>
+
+   <xsl:template match="/">
+      <xsl:value-of select="tokenize('a   b   c   d','\s+')"/>
+      <xsl:variable name="tokens" select="tokenize('a   b   c   d','\s+')"/><xsl:text>&#xa;</xsl:text>
+      <xsl:value-of select="$tokens"/>
+   </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/fn_tokenize/test12.xsl b/tests/fn_tokenize/test12.xsl
new file mode 100644
index 00000000..92983288
--- /dev/null
+++ b/tests/fn_tokenize/test12.xsl
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="3.0">
+                
+   <!-- Author: mukulg@apache.org -->
+   
+   <!-- testing the default, xslt serialization of an XDM sequence,
+        with xsl:copy-of instruction. -->
+
+   <xsl:output method="text"/>
+
+   <xsl:template match="/">
+      <xsl:variable name="tokens" select="tokenize('a   b   c   d','\s+')"/>
+      <xsl:copy-of select="$tokens"/>
+   </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/FnAbsTests.java b/tests/org/apache/xalan/xpath3/FnAbsTests.java
index 23c98d44..7e4e41d0 100644
--- a/tests/org/apache/xalan/xpath3/FnAbsTests.java
+++ b/tests/org/apache/xalan/xpath3/FnAbsTests.java
@@ -23,7 +23,7 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 
 /**
- * XPath function fn:abs test cases.
+ * XPath 3.1 function fn:abs test cases.
  * 
  * @author Mukul Gandhi <mu...@apache.org>
  * 
diff --git a/tests/org/apache/xalan/xpath3/FnAbsTests.java b/tests/org/apache/xalan/xpath3/FnIndexOfTests.java
similarity index 86%
copy from tests/org/apache/xalan/xpath3/FnAbsTests.java
copy to tests/org/apache/xalan/xpath3/FnIndexOfTests.java
index 23c98d44..7ae76568 100644
--- a/tests/org/apache/xalan/xpath3/FnAbsTests.java
+++ b/tests/org/apache/xalan/xpath3/FnIndexOfTests.java
@@ -23,17 +23,17 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 
 /**
- * XPath function fn:abs test cases.
+ * XPath 3.1 function fn:index-of test cases.
  * 
  * @author Mukul Gandhi <mu...@apache.org>
  * 
  * @xsl.usage advanced
  */
-public class FnAbsTests extends XslTransformTestsUtil {        
+public class FnIndexOfTests extends XslTransformTestsUtil {        
     
-    private static final String XSL_TRANSFORM_INPUT_DIRPATH = XSLConstants.XSL_TRANSFORM_INPUT_DIRPATH_PREFIX + "fn_abs/";
+    private static final String XSL_TRANSFORM_INPUT_DIRPATH = XSLConstants.XSL_TRANSFORM_INPUT_DIRPATH_PREFIX + "fn_indexof/";
     
-    private static final String XSL_TRANSFORM_GOLD_DIRPATH = XSLConstants.XSL_TRANSFORM_GOLD_DIRPATH_PREFIX + "fn_abs/gold/";
+    private static final String XSL_TRANSFORM_GOLD_DIRPATH = XSLConstants.XSL_TRANSFORM_GOLD_DIRPATH_PREFIX + "fn_indexof/gold/";
 
     @BeforeClass
     public static void setUpBeforeClass() throws Exception {
@@ -48,8 +48,8 @@ public class FnAbsTests extends XslTransformTestsUtil {
     }
 
     @Test
-    public void xslFnAbsTest1() {
-        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml"; 
+    public void xslFnIndexOfTest1() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl"; 
         String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl";
         
         String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test1.out";                
diff --git a/tests/org/apache/xalan/xpath3/FnStringJoinTests.java b/tests/org/apache/xalan/xpath3/FnStringJoinTests.java
index bd5418fe..119c89b1 100644
--- a/tests/org/apache/xalan/xpath3/FnStringJoinTests.java
+++ b/tests/org/apache/xalan/xpath3/FnStringJoinTests.java
@@ -23,7 +23,7 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 
 /**
- * XPath function fn:string-join test cases.
+ * XPath 3.1 function fn:string-join test cases.
  * 
  * @author Mukul Gandhi <mu...@apache.org>
  * 
diff --git a/tests/org/apache/xalan/xpath3/FnTokenizeTests.java b/tests/org/apache/xalan/xpath3/FnTokenizeTests.java
index a567536a..361ac6a4 100644
--- a/tests/org/apache/xalan/xpath3/FnTokenizeTests.java
+++ b/tests/org/apache/xalan/xpath3/FnTokenizeTests.java
@@ -23,7 +23,7 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 
 /**
- * XPath function fn:tokenize test cases.
+ * XPath 3.1 function fn:tokenize test cases.
  * 
  * @author Mukul Gandhi <mu...@apache.org>
  * 
@@ -146,5 +146,25 @@ public class FnTokenizeTests extends XslTransformTestsUtil {
         
         runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);   
     }
+    
+    @Test
+    public void xslFnTokenizeTest11() {
+        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);   
+    }
+    
+    @Test
+    public void xslFnTokenizeTest12() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test12.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test12.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test12.out";
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);   
+    }
 
 }
diff --git a/tests/org/apache/xalan/xpath3/FnUnparsedTextTests.java b/tests/org/apache/xalan/xpath3/FnUnparsedTextTests.java
index f846322c..ba1f369a 100644
--- a/tests/org/apache/xalan/xpath3/FnUnparsedTextTests.java
+++ b/tests/org/apache/xalan/xpath3/FnUnparsedTextTests.java
@@ -23,7 +23,7 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 
 /**
- * XPath function fn:unparsed-text test cases.
+ * XPath 3.1 function fn:unparsed-text test cases.
  * 
  * @author Mukul Gandhi <mu...@apache.org>
  * 
diff --git a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
index ab1205a8..76506c68 100644
--- a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
+++ b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
@@ -17,6 +17,7 @@
 package org.apache.xalan.xslt3;
 
 import org.apache.xalan.xpath3.FnAbsTests;
+import org.apache.xalan.xpath3.FnIndexOfTests;
 import org.apache.xalan.xpath3.FnStringJoinTests;
 import org.apache.xalan.xpath3.FnTokenizeTests;
 import org.apache.xalan.xpath3.FnUnparsedTextTests;
@@ -42,7 +43,8 @@ import org.junit.runners.Suite.SuiteClasses;
 @SuiteClasses({ AnalyzeStringTests.class, AttributeTests.class, GroupingTests.class,
                 GroupingWithSortTests.class, RtfMigrationTests.class, QuantifiedExprTests.class, 
                 FnUnparsedTextTests.class, FnTokenizeTests.class, FnStringJoinTests.class,
-                FnAbsTests.class, StringTests.class, XsConstructorFunctions.class })
+                FnAbsTests.class, StringTests.class, XsConstructorFunctions.class, 
+                FnIndexOfTests.class })
 public class AllXsl3Tests {
 
 }
diff --git a/tests/org/apache/xalan/xslt3/AnalyzeStringTests.java b/tests/org/apache/xalan/xslt3/AnalyzeStringTests.java
index 9d47835c..0b8dbef9 100644
--- a/tests/org/apache/xalan/xslt3/AnalyzeStringTests.java
+++ b/tests/org/apache/xalan/xslt3/AnalyzeStringTests.java
@@ -155,5 +155,25 @@ public class AnalyzeStringTests extends XslTransformTestsUtil {
         
         runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
     }
+    
+    @Test
+    public void xslAnalyzeStringTest12() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test12.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test12.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test12.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslAnalyzeStringTest13() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_h.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test13.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test13.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