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/08/31 09:20:06 UTC

[xalan-java] branch xalan-j_xslt3.0 updated: committing implementation of xpath 3.1 function fn:contains-token, along with few new related test cases as well. also committing implementation of 'html ascii case-insensitive collation', as described by xpath 3.1 f&o spec.

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 745bda3c committing implementation of xpath 3.1 function fn:contains-token, along with few new related test cases as well. also committing implementation of 'html ascii case-insensitive collation', as described by xpath 3.1 f&o spec.
     new 865966b0 Merge pull request #71 from mukulga/xalan-j_xslt3.0_mukul
745bda3c is described below

commit 745bda3cc9167c778290007beccb6702f7a6f022
Author: Mukul Gandhi <ga...@gmail.com>
AuthorDate: Thu Aug 31 14:44:51 2023 +0530

    committing implementation of xpath 3.1 function fn:contains-token, along with few new related test cases as well. also committing implementation of 'html ascii case-insensitive collation', as described by xpath 3.1 f&o spec.
---
 src/org/apache/xpath/XPathCollationSupport.java    |  50 +++++-
 src/org/apache/xpath/compiler/FunctionTable.java   |   9 +-
 src/org/apache/xpath/compiler/Keywords.java        |   3 +
 .../apache/xpath/functions/FuncContainsToken.java  | 190 +++++++++++++++++++++
 tests/fn_containstoken/gold/test1.out              |   6 +
 tests/fn_containstoken/gold/test2.out              |   7 +
 tests/fn_containstoken/test1.xsl                   |  55 ++++++
 tests/fn_containstoken/test1_a.xml                 |   7 +
 tests/fn_containstoken/test2.xsl                   |  58 +++++++
 .../apache/xalan/xpath3/FnContainsTokenTests.java  |  72 ++++++++
 tests/org/apache/xalan/xslt3/AllXsl3Tests.java     |   3 +-
 11 files changed, 455 insertions(+), 5 deletions(-)

diff --git a/src/org/apache/xpath/XPathCollationSupport.java b/src/org/apache/xpath/XPathCollationSupport.java
index 64569389..972382cc 100644
--- a/src/org/apache/xpath/XPathCollationSupport.java
+++ b/src/org/apache/xpath/XPathCollationSupport.java
@@ -132,9 +132,53 @@ public class XPathCollationSupport {
           }    
        }
        else if (HTML_ASCII_CASE_INSENSITIVE_COLLATION_URI.equals(collationUri)) {
-          // REVISIT
-          throw new javax.xml.transform.TransformerException("FOCH0002 : The requested collation '" + collationUri + "' "
-                                                                                                           + "is not supported.");          
+          int str1Len = str1.length();
+          int str2Len = str2.length();
+           
+          int idx1 = 0;
+          int idx2 = 0;
+           
+          while (true) {
+             if (idx1 == str1Len) {
+                if (idx2 == str2Len) {
+                   comparisonResult = 0;
+                   break;
+                } else {
+                   comparisonResult = -1;
+                   break;
+                }
+             }
+             
+             if (idx2 == str2Len) {
+                comparisonResult = 1;
+                break;
+             }
+             
+             int codepoint1 = str1.codePointAt(idx1);
+             idx1 += 1;
+             
+             int codepoint2 = str2.codePointAt(idx2);
+             idx2 += 1;
+             
+             if ((codepoint1 >= 'a') && (codepoint1 <= 'z')) {
+                codepoint1 += 'A' - 'a';
+             }
+             
+             if ((codepoint2 >= 'a') && (codepoint2 <= 'z')) {
+                codepoint2 += 'A' - 'a';
+             }
+             
+             int codepointDiff = codepoint1 - codepoint2;             
+             if (codepointDiff != 0) {
+                if (codepointDiff < 0) {
+                   comparisonResult = -1;
+                }
+                else {
+                   comparisonResult = 1; 
+                }                
+                break;
+             }
+          }          
        }
        else {
           throw new javax.xml.transform.TransformerException("FOCH0002 : The requested collation '" + collationUri + "' "
diff --git a/src/org/apache/xpath/compiler/FunctionTable.java b/src/org/apache/xpath/compiler/FunctionTable.java
index 7b62e43f..0b72faac 100644
--- a/src/org/apache/xpath/compiler/FunctionTable.java
+++ b/src/org/apache/xpath/compiler/FunctionTable.java
@@ -317,6 +317,9 @@ public class FunctionTable
   
   /** The 'min()' id. */
   public static final int FUNC_MIN = 97;
+  
+  /** The 'contains-token()' id. */
+  public static final int FUNC_CONTAINS_TOKEN = 98;
 
   // Proprietary
 
@@ -374,7 +377,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 = 98;
+  private static final int NUM_BUILT_IN_FUNCS = 99;
 
   /**
    * Number of built-in functions that may be added.
@@ -541,6 +544,8 @@ public class FunctionTable
       org.apache.xpath.functions.FuncCompare.class;
     m_functions[FUNC_CODEPOINT_EQUAL] = 
       org.apache.xpath.functions.FuncCodepointEqual.class;
+    m_functions[FUNC_CONTAINS_TOKEN] = 
+      org.apache.xpath.functions.FuncContainsToken.class;
     
     m_functions[FUNC_EMPTY] = 
       org.apache.xpath.functions.FuncEmpty.class;
@@ -742,6 +747,8 @@ public class FunctionTable
                          new Integer(FunctionTable.FUNC_COMPARE));
          m_functionID.put(Keywords.FUNC_CODEPOINT_EQUAL,
                          new Integer(FunctionTable.FUNC_CODEPOINT_EQUAL));
+         m_functionID.put(Keywords.FUNC_CONTAINS_TOKEN,
+                         new Integer(FunctionTable.FUNC_CONTAINS_TOKEN));
          
          m_functionID.put(Keywords.FUNC_EMPTY,
                          new Integer(FunctionTable.FUNC_EMPTY));
diff --git a/src/org/apache/xpath/compiler/Keywords.java b/src/org/apache/xpath/compiler/Keywords.java
index fa281598..cf7a46dc 100644
--- a/src/org/apache/xpath/compiler/Keywords.java
+++ b/src/org/apache/xpath/compiler/Keywords.java
@@ -353,6 +353,9 @@ public class Keywords
   /** codepoint-equal function string. */
   public static final String FUNC_CODEPOINT_EQUAL = "codepoint-equal";
   
+  /** contains-token function string. */
+  public static final String FUNC_CONTAINS_TOKEN = "contains-token";
+  
   // XML Schema built-in data type name keywords
   
   /** xs:string data type string. */
diff --git a/src/org/apache/xpath/functions/FuncContainsToken.java b/src/org/apache/xpath/functions/FuncContainsToken.java
new file mode 100644
index 00000000..f0a47ffa
--- /dev/null
+++ b/src/org/apache/xpath/functions/FuncContainsToken.java
@@ -0,0 +1,190 @@
+/*
+ * 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.util.ArrayList;
+import java.util.List;
+
+import javax.xml.transform.SourceLocator;
+
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.xslt.util.XslTransformEvaluationHelper;
+import org.apache.xml.dtm.DTM;
+import org.apache.xml.dtm.DTMIterator;
+import org.apache.xml.dtm.DTMManager;
+import org.apache.xpath.Expression;
+import org.apache.xpath.XPathCollationSupport;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.ResultSequence;
+import org.apache.xpath.objects.XNodeSet;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.res.XPATHErrorResources;
+import org.apache.xpath.xs.types.XSBoolean;
+
+/**
+ * Implementation of an XPath 3.1 function contains-token().
+ * 
+ * Ref : https://www.w3.org/TR/xpath-functions-31/#func-contains-token
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class FuncContainsToken extends FunctionMultiArgs {
+
+   private static final long serialVersionUID = -7113398825278491809L;
+
+   /**
+   * 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
+   {      
+        ResultSequence result = new ResultSequence();
+        
+        SourceLocator srcLocator = xctxt.getSAXLocator();
+        
+        Expression arg0 = getArg0();
+        Expression arg1 = getArg1();
+        Expression arg2 = getArg2();
+        
+        if ((arg0 == null) || (arg1 == null)) {
+           // return an empty sequence, if first two mandatory arguments are not
+           // present within function call fn:contains-token. 
+           return result; 
+        }
+        
+        XObject arg0EvalResult = arg0.execute(xctxt);
+        
+        List<String> arg0StrList = new ArrayList<String>();
+        
+        if (arg0EvalResult instanceof XNodeSet) {
+           XNodeSet nodeSet = (XNodeSet)arg0EvalResult;
+           if (nodeSet.getLength() > 0) {
+               DTMManager dtmMgr = (DTMManager)xctxt;                        
+               DTMIterator sourceNodes = nodeSet.iter();
+               
+               int nextNodeDtmHandle;
+               while ((nextNodeDtmHandle = sourceNodes.nextNode()) != DTM.NULL) {
+                  XNodeSet xNodeSetItem = new XNodeSet(nextNodeDtmHandle, dtmMgr);
+                  String strVal = xNodeSetItem.str();
+                  arg0StrList.add(strVal);
+               }
+           }
+           else {
+              result.add(new XSBoolean(false));
+           }
+        }
+        else if (arg0EvalResult instanceof ResultSequence) {
+           ResultSequence resultSeq = (ResultSequence)arg0EvalResult;
+           if (resultSeq.size() > 0) {
+              for (int idx = 0; idx < resultSeq.size(); idx++) {
+                 XObject xObject = resultSeq.item(idx); 
+                 String strVal = XslTransformEvaluationHelper.getStrVal(xObject);
+                 arg0StrList.add(strVal);
+              }
+           }
+           else {
+              result.add(new XSBoolean(false)); 
+           }
+        }
+        else {
+           arg0StrList.add(arg0EvalResult.str()); 
+        }        
+        
+        XObject arg1EvalResult = arg1.execute(xctxt);
+        
+        String tokenStrVal = XslTransformEvaluationHelper.getStrVal(arg1EvalResult);
+        tokenStrVal = tokenStrVal.trim();
+        
+        if (tokenStrVal.length() > 0) {
+           String collationUri = null;
+           if (arg2 == null) {
+              collationUri = xctxt.getDefaultCollation();  
+           }
+           else {
+              XObject arg2EvalResult = arg2.execute(xctxt);
+              collationUri = XslTransformEvaluationHelper.getStrVal(arg2EvalResult); 
+           }
+           
+           XPathCollationSupport xpathCollationSupport = xctxt.getXPathCollationSupport();
+           
+           boolean isTokenExists = false;
+           
+           for (int idx1 = 0; idx1 < arg0StrList.size(); idx1++) {
+              String strVal = arg0StrList.get(idx1);
+              // split this string at whitespace boundaries
+              String[] strPartsArr = strVal.split("\s+");
+              for (int idx2 = 0; idx2 < strPartsArr.length; idx2++) {
+                 String strPart = strPartsArr[idx2];
+                 if (xpathCollationSupport.compareStringsUsingCollation(strPart, tokenStrVal, 
+                                                                                       collationUri) == 0) {
+                    result.add(new XSBoolean(true));
+                    isTokenExists = true;
+                    break;
+                 }
+              }
+              
+              if (isTokenExists) {
+                 break; 
+              }
+           }
+           
+           if (!isTokenExists) {
+              result.add(new XSBoolean(false)); 
+           }
+        }
+        else {
+           result.add(new XSBoolean(false)); 
+        }
+                    
+        return result;
+   }
+
+  /**
+   * 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/tests/fn_containstoken/gold/test1.out b/tests/fn_containstoken/gold/test1.out
new file mode 100644
index 00000000..304c06dc
--- /dev/null
+++ b/tests/fn_containstoken/gold/test1.out
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>true</one>
+  <two>true</two>
+  <three>false</three>
+  <four>true</four>
+</result>
diff --git a/tests/fn_containstoken/gold/test2.out b/tests/fn_containstoken/gold/test2.out
new file mode 100644
index 00000000..fc9d73c6
--- /dev/null
+++ b/tests/fn_containstoken/gold/test2.out
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?><result>
+  <one>true</one>
+  <two>false</two>
+  <three>true</three>
+  <four>true</four>
+  <five>false</five>
+</result>
diff --git a/tests/fn_containstoken/test1.xsl b/tests/fn_containstoken/test1.xsl
new file mode 100644
index 00000000..bf2f7dc5
--- /dev/null
+++ b/tests/fn_containstoken/test1.xsl
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="3.0">
+                
+    <!-- Author: mukulg@apache.org -->
+    
+    <!-- This XSLT stylesheet test case, tests the XPath 3.1 function 
+         fn:contains-token.
+         
+         Within this stylesheet, the XPath expression examples for the
+         function fn:contains-token are borrowed from XPath 3.1 F&O spec.
+    -->                
+    
+    <xsl:output method="xml" indent="yes"/>
+    
+    <xsl:variable name="seq1" select="('red', 'green', 'blue')"/>
+    
+    <xsl:variable name="collationUri" select="'http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive'"/>
+        
+    <xsl:template match="/">
+       <result>
+         <one>
+            <xsl:value-of select="contains-token('red green blue ', 'red')"/> 
+         </one>
+         <two>            
+            <xsl:value-of select="contains-token($seq1, ' red ')"/>
+         </two>
+         <three>            
+	        <xsl:value-of select="contains-token('red, green, blue', 'red')"/>
+         </three>
+         <four>            
+	        <xsl:value-of select="contains-token('red green blue', 'RED', $collationUri)"/>
+         </four>
+       </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_containstoken/test1_a.xml b/tests/fn_containstoken/test1_a.xml
new file mode 100644
index 00000000..0e40ab1e
--- /dev/null
+++ b/tests/fn_containstoken/test1_a.xml
@@ -0,0 +1,7 @@
+<info>
+  <val1>red green blue </val1>
+  <val2>red, green, blue</val2>
+  <val3>red green blue</val3>  
+  <data1 val="red green blue "/>
+  <data2 val="red, green, blue"/>
+</info>
\ No newline at end of file
diff --git a/tests/fn_containstoken/test2.xsl b/tests/fn_containstoken/test2.xsl
new file mode 100644
index 00000000..b292699a
--- /dev/null
+++ b/tests/fn_containstoken/test2.xsl
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+                version="3.0">
+    
+    <!-- Author: mukulg@apache.org -->
+    
+    <!-- use with test1_a.xml -->
+    
+    <!-- This XSLT stylesheet test case, tests the XPath 3.1 function 
+         fn:contains-token.
+         
+         This stylesheet example, reads input data to be transformed
+         from an XML external document.
+    -->
+    
+    <xsl:output method="xml" indent="yes"/>
+    
+    <xsl:variable name="collationUri" select="'http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive'"/>
+        
+    <xsl:template match="/info">
+       <result>
+         <one>
+            <xsl:value-of select="contains-token(val1, 'red')"/> 
+         </one>
+         <two>            
+	        <xsl:value-of select="contains-token(val2, 'red')"/>
+         </two>
+         <three>            
+	        <xsl:value-of select="contains-token(val3, 'RED', $collationUri)"/>
+         </three>
+         <four>            
+	        <xsl:value-of select="contains-token(data1/@val, 'red')"/>
+         </four>
+         <five>            
+	        <xsl:value-of select="contains-token(data2/@val, 'red')"/>
+         </five>
+       </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/FnContainsTokenTests.java b/tests/org/apache/xalan/xpath3/FnContainsTokenTests.java
new file mode 100644
index 00000000..a96ef428
--- /dev/null
+++ b/tests/org/apache/xalan/xpath3/FnContainsTokenTests.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.xalan.xpath3;
+
+import org.apache.xalan.util.XslTransformTestsUtil;
+import org.apache.xalan.xslt3.XSLConstants;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * XPath 3.1 function fn:contains-token test cases.
+ * 
+ * @author Mukul Gandhi <mu...@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class FnContainsTokenTests extends XslTransformTestsUtil {        
+    
+    private static final String XSL_TRANSFORM_INPUT_DIRPATH = XSLConstants.XSL_TRANSFORM_INPUT_DIRPATH_PREFIX 
+                                                                                                    + "fn_containstoken/";
+    
+    private static final String XSL_TRANSFORM_GOLD_DIRPATH = XSLConstants.XSL_TRANSFORM_GOLD_DIRPATH_PREFIX 
+                                                                                                    + "fn_containstoken/gold/";
+
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        // no op
+    }
+
+    @AfterClass
+    public static void tearDownAfterClass() throws Exception {        
+        xmlDocumentBuilderFactory = null;
+        xmlDocumentBuilder = null;
+        xslTransformerFactory = null;
+    }
+
+    @Test
+    public void xslFnContainsTokenTest1() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test1.out";                
+        
+        runXslTransformAndAssertOutput(xmlFilePath, xslFilePath, goldFilePath, null);
+    }
+    
+    @Test
+    public void xslFnContainsTokenTest2() {
+        String xmlFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test1_a.xml"; 
+        String xslFilePath = XSL_TRANSFORM_INPUT_DIRPATH + "test2.xsl";
+        
+        String goldFilePath = XSL_TRANSFORM_GOLD_DIRPATH + "test2.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 dcdc8216..9153e9b6 100644
--- a/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
+++ b/tests/org/apache/xalan/xslt3/AllXsl3Tests.java
@@ -23,6 +23,7 @@ import org.apache.xalan.xpath3.FnAvgTests;
 import org.apache.xalan.xpath3.FnCodepointEqualTests;
 import org.apache.xalan.xpath3.FnCodepointsToStringTests;
 import org.apache.xalan.xpath3.FnCompareTests;
+import org.apache.xalan.xpath3.FnContainsTokenTests;
 import org.apache.xalan.xpath3.FnDistinctValuesTests;
 import org.apache.xalan.xpath3.FnFilterTests;
 import org.apache.xalan.xpath3.FnFoldLeftTests;
@@ -90,7 +91,7 @@ import org.junit.runners.Suite.SuiteClasses;
                 FnFoldRightTests.class, FnForEachPairTests.class, FnSortTests.class, FnCodepointsToStringTests.class,
                 FnStringToCodepointsTests.class, FnCompareTests.class, FnCodepointEqualTests.class,
                 SequenceFunctionTests.class, FnParseXmlTests.class, FnParseXmlFragmentTests.class,
-                TemplateTests.class, FnAvgTests.class, FnMaxTests.class, FnMinTests.class })
+                TemplateTests.class, FnAvgTests.class, FnMaxTests.class, FnMinTests.class, FnContainsTokenTests.class })
 public class AllXsl3Tests {
 
 }


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