[prev in list] [next in list] [prev in thread] [next in thread] 

List:       xalan-cvs
Subject:    [xalan-java] branch xalan-j_xslt3.0 updated: committing implementation of xpath 3.1 fn:tokenize() fu
From:       mukulg () apache ! org
Date:       2023-05-21 15:50:31
Message-ID: 168468423153.987071.6365233914961336981 () gitbox2-he-fi ! apache ! org
[Download RAW message or body]

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 4962a3c5 committing implementation of xpath 3.1 fn:tokenize() function, and \
related enhancements to xalanj codebase on dev branch xalan-j_xslt3.0 4962a3c5 is \
described below

commit 4962a3c5ca3dc8fd1974ad124767ee8799a297fa
Author: Mukul Gandhi <gandhi.mukul@gmail.com>
AuthorDate: Sun May 21 21:20:10 2023 +0530

    committing implementation of xpath 3.1 fn:tokenize() function, and related \
                enhancements to xalanj codebase on dev branch xalan-j_xslt3.0
---
 src/org/apache/xalan/templates/ElemForEach.java   |  43 ++++-
 src/org/apache/xalan/templates/ElemValueOf.java   |  12 +-
 src/org/apache/xpath/XPathContext.java            |  12 +-
 src/org/apache/xpath/compiler/FunctionTable.java  |  15 +-
 src/org/apache/xpath/compiler/Keywords.java       |   5 +-
 src/org/apache/xpath/functions/FuncCount.java     |  42 ++---
 src/org/apache/xpath/functions/FuncTokenize.java  | 206 ++++++++++++++++++++++
 src/org/apache/xpath/objects/ResultSequence.java  |  55 ++++++
 src/org/apache/xpath/res/XPATHErrorResources.java |   5 +
 9 files changed, 360 insertions(+), 35 deletions(-)

diff --git a/src/org/apache/xalan/templates/ElemForEach.java \
b/src/org/apache/xalan/templates/ElemForEach.java index 7f4123a6..eae82f1f 100644
--- a/src/org/apache/xalan/templates/ElemForEach.java
+++ b/src/org/apache/xalan/templates/ElemForEach.java
@@ -20,6 +20,7 @@
  */
 package org.apache.xalan.templates;
 
+import java.util.List;
 import java.util.Vector;
 
 import javax.xml.transform.TransformerException;
@@ -34,6 +35,9 @@ import org.apache.xpath.Expression;
 import org.apache.xpath.ExpressionOwner;
 import org.apache.xpath.XPath;
 import org.apache.xpath.XPathContext;
+import org.apache.xpath.functions.Function;
+import org.apache.xpath.objects.ResultSequence;
+import org.apache.xpath.objects.XObject;
 
 import java.io.ObjectInputStream;
 import java.io.IOException;
@@ -326,14 +330,36 @@ public class ElemForEach extends ElemTemplateElement implements \
                ExpressionOwner
    * @throws TransformerException Thrown in a variety of circumstances.
    * @xsl.usage advanced
    */
-  public void transformSelectedNodes(TransformerImpl transformer)
-          throws TransformerException
-  {
+  public void transformSelectedNodes(TransformerImpl transformer) throws 
+                                                             TransformerException {
 
-    final XPathContext xctxt = transformer.getXPathContext();
+    final XPathContext xctxtOriginal = transformer.getXPathContext();
+    
+    XPathContext xctxt = transformer.getXPathContext();
+    
+    if (m_selectExpression instanceof Function) {
+        XObject evalResult = ((Function)m_selectExpression).execute(xctxt);
+        if (evalResult instanceof ResultSequence) {
+            ResultSequence resultSeq = (ResultSequence)evalResult;
+            List<XObject> resultSeqItems = resultSeq.getResultSequenceItems();
+            for (int idx = 0; idx < resultSeqItems.size(); idx++) {
+                XObject resultSeqItem = resultSeqItems.get(idx);
+                xctxt.setXPath3ContextItem(resultSeqItem);
+                
+                for (ElemTemplateElement elemTemplateElem = this.m_firstChild; \
elemTemplateElem != null;  +                                                          \
elemTemplateElem = elemTemplateElem.m_nextSibling) { +                   \
xctxt.setSAXLocator(elemTemplateElem); +                   \
transformer.setCurrentElement(elemTemplateElem); +                   \
elemTemplateElem.execute(transformer); +                }
+            }
+            
+            return;
+        }                
+    }
+    
     final int sourceNode = xctxt.getCurrentNode();
-    DTMIterator sourceNodes = m_selectExpression.asIterator(xctxt,
-            sourceNode);
+    DTMIterator sourceNodes = m_selectExpression.asIterator(xctxt, sourceNode);
 
     try
     {
@@ -471,6 +497,11 @@ public class ElemForEach extends ElemTemplateElement implements \
ExpressionOwner  xctxt.popCurrentNode();
       sourceNodes.detach();
     }
+    
+    // restoring the xpath context, to where it was before this 
+    // xsl:for-each instruction began an evaluation.
+    transformer.setXPathContext(xctxtOriginal);
+    
   }
 
   /**
diff --git a/src/org/apache/xalan/templates/ElemValueOf.java \
b/src/org/apache/xalan/templates/ElemValueOf.java index 5cf4d4d7..d32e6a80 100644
--- a/src/org/apache/xalan/templates/ElemValueOf.java
+++ b/src/org/apache/xalan/templates/ElemValueOf.java
@@ -42,6 +42,7 @@ import org.xml.sax.SAXException;
  * >
  * </pre>
  * @see <a href="http://www.w3.org/TR/xslt#value-of">value-of in XSLT \
Specification</a> + * 
  * @xsl.usage advanced
  */
 public class ElemValueOf extends ElemTemplateElement
@@ -50,13 +51,11 @@ public class ElemValueOf extends ElemTemplateElement
 
   /**
    * The select expression to be executed.
-   * @serial
    */
   private XPath m_selectExpression = null;
 
   /**
    * True if the pattern is a simple ".".
-   * @serial
    */
   private boolean m_isDot = false;
 
@@ -271,7 +270,14 @@ public class ElemValueOf extends ElemTemplateElement
           }
           else
           {
-            expr.executeCharsToContentHandler(xctxt, rth);
+              XObject xpath3ContextItem = xctxt.getXPath3ContextItem();
+              if (m_isDot && xpath3ContextItem != null) {
+                  // this is currently, limited to work with xsl:for-each \
instruction +                  xpath3ContextItem.dispatchCharactersEvents(rth);   
+              }
+              else {
+                  expr.executeCharsToContentHandler(xctxt, rth);
+              }
           }
         }
         finally
diff --git a/src/org/apache/xpath/XPathContext.java \
b/src/org/apache/xpath/XPathContext.java index 936edbd4..97f12a6a 100644
--- a/src/org/apache/xpath/XPathContext.java
+++ b/src/org/apache/xpath/XPathContext.java
@@ -58,7 +58,6 @@ import org.xml.sax.XMLReader;
 /**
  * Default class for the runtime execution context for XPath.
  * 
- * <p>This class extends DTMManager but does not directly implement it.</p>
  * @xsl.usage advanced
  */
 public class XPathContext extends DTMManager // implements ExpressionContext
@@ -95,6 +94,9 @@ public class XPathContext extends DTMManager // implements \
                ExpressionContext
    */
   private boolean m_isSecureProcessing = false;
   
+  // supporting XPath 3.1 context item, to be saved within current XPath context
+  private XObject m_xpath3ContextItem = null;
+  
   /*
    * This field, can be used to store custom data (represented as a map object) 
    * within the current XPath evaluation context.
@@ -1364,5 +1366,13 @@ public class XPathContext extends DTMManager // implements \
ExpressionContext  public void setCustomDataMap(Map<String, String> customDataMap) {
     this.m_customDataMap = customDataMap;
  }
+
+ public XObject getXPath3ContextItem() {
+     return m_xpath3ContextItem;
+ }
+
+ public void setXPath3ContextItem(XObject xpath3ContextItem) {
+     this.m_xpath3ContextItem = xpath3ContextItem;
+ }
   
 }
diff --git a/src/org/apache/xpath/compiler/FunctionTable.java \
b/src/org/apache/xpath/compiler/FunctionTable.java index 07225ed1..dfa19f14 100644
--- a/src/org/apache/xpath/compiler/FunctionTable.java
+++ b/src/org/apache/xpath/compiler/FunctionTable.java
@@ -149,6 +149,9 @@ public class FunctionTable
   
   /** The 'regex-group()' id (XSLT). */
   public static final int FUNC_REGEX_GROUP = 42;
+  
+  /** The 'tokenize()' id. */
+  public static final int FUNC_TOKENIZE = 43;
 
   // Proprietary
 
@@ -177,7 +180,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 = 43;
+  private static final int NUM_BUILT_IN_FUNCS = 44;
 
   /**
    * Number of built-in functions that may be added.
@@ -255,6 +258,8 @@ public class FunctionTable
       org.apache.xpath.functions.FuncAbs.class;
     m_functions[FUNC_REGEX_GROUP] = 
       org.apache.xalan.templates.FuncRegexGroup.class;
+    m_functions[FUNC_TOKENIZE] = 
+      org.apache.xpath.functions.FuncTokenize.class;
   }
 
   static{
@@ -317,7 +322,7 @@ public class FunctionTable
           m_functionID.put(Keywords.FUNC_SYSTEM_PROPERTY_STRING,
                           new Integer(FunctionTable.FUNC_SYSTEM_PROPERTY));
           m_functionID.put(Keywords.FUNC_EXT_FUNCTION_AVAILABLE_STRING,
-                        new Integer(FunctionTable.FUNC_EXT_FUNCTION_AVAILABLE));
+                          new Integer(FunctionTable.FUNC_EXT_FUNCTION_AVAILABLE));
           m_functionID.put(Keywords.FUNC_EXT_ELEM_AVAILABLE_STRING,
                           new Integer(FunctionTable.FUNC_EXT_ELEM_AVAILABLE));
           m_functionID.put(Keywords.FUNC_SUBSTRING_STRING,
@@ -337,9 +342,11 @@ public class FunctionTable
           m_functionID.put(Keywords.FUNC_CURRENT_GROUP,
                           new Integer(FunctionTable.FUNC_CURRENT_GROUP));
           m_functionID.put(Keywords.FUNC_ABS,
-                  new Integer(FunctionTable.FUNC_ABS));
+                          new Integer(FunctionTable.FUNC_ABS));
           m_functionID.put(Keywords.FUNC_REGEX_GROUP,
-                  new Integer(FunctionTable.FUNC_REGEX_GROUP));
+                          new Integer(FunctionTable.FUNC_REGEX_GROUP));
+          m_functionID.put(Keywords.FUNC_TOKENIZE,
+                          new Integer(FunctionTable.FUNC_TOKENIZE));
   }
   
   public FunctionTable(){
diff --git a/src/org/apache/xpath/compiler/Keywords.java \
b/src/org/apache/xpath/compiler/Keywords.java index a8cc969c..d303646f 100644
--- a/src/org/apache/xpath/compiler/Keywords.java
+++ b/src/org/apache/xpath/compiler/Keywords.java
@@ -225,6 +225,9 @@ public class Keywords
   
   /** regex-group function string (XSLT). */
   public static final String FUNC_REGEX_GROUP = "regex-group";
+  
+  /** tokenize function string. */
+  public static final String FUNC_TOKENIZE = "tokenize";
 
   // Proprietary, built in functions
 
@@ -286,7 +289,7 @@ public class Keywords
                     new Integer(OpCodes.NODETYPE_NODE));
     
     m_keywords.put(FUNC_KEY_STRING,
-            new Integer(FunctionTable.FUNC_KEY));
+                    new Integer(FunctionTable.FUNC_KEY));
   }
   
   static Object getAxisName(String key){
diff --git a/src/org/apache/xpath/functions/FuncCount.java \
b/src/org/apache/xpath/functions/FuncCount.java index 4bca77fb..c4981963 100644
--- a/src/org/apache/xpath/functions/FuncCount.java
+++ b/src/org/apache/xpath/functions/FuncCount.java
@@ -21,12 +21,15 @@
 package org.apache.xpath.functions;
 
 import org.apache.xml.dtm.DTMIterator;
+import org.apache.xpath.Expression;
 import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.ResultSequence;
 import org.apache.xpath.objects.XNumber;
 import org.apache.xpath.objects.XObject;
 
 /**
- * Execute the Count() function.
+ * Execute the count() function.
+ * 
  * @xsl.usage advanced
  */
 public class FuncCount extends FunctionOneArg
@@ -34,8 +37,8 @@ public class FuncCount extends FunctionOneArg
     static final long serialVersionUID = -7116225100474153751L;
 
   /**
-   * Execute the function.  The function must return
-   * a valid object.
+   * Execute the function. The function must return a valid object.
+   * 
    * @param xctxt The current execution context.
    * @return A valid XObject.
    *
@@ -43,22 +46,21 @@ public class FuncCount extends FunctionOneArg
    */
   public XObject execute(XPathContext xctxt) throws \
javax.xml.transform.TransformerException  {
-
-//    DTMIterator nl = m_arg0.asIterator(xctxt, xctxt.getCurrentNode());
-
-//    // We should probably make a function on the iterator for this, 
-//    // as a given implementation could optimize.
-//    int i = 0;
-//
-//    while (DTM.NULL != nl.nextNode())
-//    {
-//      i++;
-//    }
-//    nl.detach();
-	DTMIterator nl = m_arg0.asIterator(xctxt, xctxt.getCurrentNode());
-	int i = nl.getLength();	
-	nl.detach();
-
-    return new XNumber((double) i);
+        int count = 0;
+        
+        if (m_arg0 instanceof Function) {
+            XObject evalResult = ((Function)m_arg0).execute(xctxt);
+            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();	
+            nl.detach();
+        }
+    
+        return new XNumber((double)count);    
   }
+  
 }
diff --git a/src/org/apache/xpath/functions/FuncTokenize.java \
b/src/org/apache/xpath/functions/FuncTokenize.java new file mode 100644
index 00000000..50738647
--- /dev/null
+++ b/src/org/apache/xpath/functions/FuncTokenize.java
@@ -0,0 +1,206 @@
+/*
+ * 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.
+ */
+/*
+ * $Id$
+ */
+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.xml.utils.XMLString;
+import org.apache.xml.utils.XMLStringFactory;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.ResultSequence;
+import org.apache.xpath.objects.XMLStringFactoryImpl;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XString;
+import org.apache.xpath.regex.Matcher;
+import org.apache.xpath.regex.PatternSyntaxException;
+import org.apache.xpath.res.XPATHErrorResources;
+
+/**
+ * Execute the tokenize() function.
+ * 
+ * @author Mukul Gandhi <mukulg@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class FuncTokenize extends Function3Args {
+
+  private static final long serialVersionUID = -7790625909187393478L;
+  
+  private static final String FUNCTION_NAME = "tokenize()"; 
+
+  /**
+   * 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();
+        
+        XMLString inputStr = m_arg0.execute(xctxt).xstr();
+        
+        if (m_arg1 == null && m_arg2 == null) {
+            // while calling this function, if only first argument is present, then \
this  +            // function splits the supplied string at whitespace boundaries. \
i.e, fn:tokenize($input) is  +            // equivalent to calling \
fn:tokenize(fn:normalize-space($input), ' ')) where the second  +            // \
argument is a single space character (x20). +            XMLString effectiveInpStr = \
inputStr.fixWhiteSpace(true, true, false);             +            char[] buf = new \
char[1]; +            buf[0] = ' ';
+            XMLStringFactory xsf = XMLStringFactoryImpl.getFactory();
+            XMLString pattern = xsf.newstr(new String(buf, 0, 1));
+            
+            List<String> tokenList = null;
+            
+            try {
+               tokenList = tokenize(pattern.toString(), null, \
effectiveInpStr.toString()); +            }
+            catch (PatternSyntaxException ex) {
+                throw new \
javax.xml.transform.TransformerException(XSLMessages.createXPATHMessage(XPATHErrorResources.
 +                                                          ER_INVALID_REGEX, new \
Object[]{ FUNCTION_NAME }), srcLocator);    +            }
+            catch (Exception ex) {
+                throw new javax.xml.transform.TransformerException(ex.getMessage(), \
srcLocator);  +            }
+            
+            ResultSequence resultSeq = new ResultSequence();
+            for (int idx = 0; idx < tokenList.size(); idx++) {
+                resultSeq.add(new XString(tokenList.get(idx)));    
+            }
+            
+            return resultSeq;
+        }
+        
+        XMLString pattern = null;
+        
+        if (m_arg1 != null) {
+            pattern = m_arg1.execute(xctxt).xstr();  
+        }
+        
+        XMLString flags = null;
+        
+        if (m_arg2 != null) {
+           flags = m_arg2.execute(xctxt).xstr();
+           if (!RegexEvaluationSupport.isFlagStrValid(flags.toString())) {           \
 +              throw new \
javax.xml.transform.TransformerException(XSLMessages.createXPATHMessage(XPATHErrorResources.
 +                                                                       \
ER_INVALID_REGEX_FLAGS, new Object[]{ FUNCTION_NAME }), +                             \
srcLocator);  +           }
+        }
+        
+        String flagsStr = (flags != null) ? flags.toString() : null;
+        
+        List<String> tokenList = null;
+        
+        try {
+           tokenList = tokenize(pattern.toString(), flagsStr, inputStr.toString());
+        }
+        catch (PatternSyntaxException ex) {
+           throw new \
javax.xml.transform.TransformerException(XSLMessages.createXPATHMessage(XPATHErrorResources.
 +                                                         ER_INVALID_REGEX, new \
Object[]{ FUNCTION_NAME }), srcLocator);   +        }
+        catch (Exception ex) {
+           throw new javax.xml.transform.TransformerException(ex.getMessage(), \
srcLocator);    +        }
+    
+        ResultSequence resultSeq = new ResultSequence();
+        for (int idx = 0; idx < tokenList.size(); idx++) {
+            resultSeq.add(new XString(tokenList.get(idx)));    
+        }
+        
+        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 == 1 || 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_ONE_TWO_OR_THREE, null)); //"1, 2 or 3" +  }
+  
+  private List<String> tokenize(String pattern, String flags, String inputStr) \
throws  +                                                                \
PatternSyntaxException, Exception { +
+      List<String> tokens = new ArrayList<String>();
+
+      Matcher regexMatcher = null;
+
+      try {
+          regexMatcher = \
RegexEvaluationSupport.regex(RegexEvaluationSupport.trfPatternStrForSubtraction( +    \
pattern.toString()), flags != null ? flags.toString() :  +                            \
null, inputStr.toString()); +      }
+      catch (PatternSyntaxException ex) {
+          throw ex;   
+      }
+
+      int startpos = 0;
+      int endpos = inputStr.length();
+
+      while (regexMatcher.find()) {
+          String delim = regexMatcher.group();
+          if (delim.length() == 0) {
+              throw new Exception("FORX0003 : The regular expression must not match \
zero-length string."); +          }
+          String token = inputStr.substring(startpos, regexMatcher.start());
+          startpos = regexMatcher.end();
+          tokens.add(token);
+      }
+
+      if (startpos < endpos) {
+          String token = inputStr.substring(startpos, endpos);
+          tokens.add(token);
+      }
+      else if (startpos == endpos) {
+          tokens.add("");
+      }
+
+      return tokens;
+  }
+  
+}
diff --git a/src/org/apache/xpath/objects/ResultSequence.java \
b/src/org/apache/xpath/objects/ResultSequence.java new file mode 100644
index 00000000..ab9fd85a
--- /dev/null
+++ b/src/org/apache/xpath/objects/ResultSequence.java
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+/*
+ * $Id$
+ */
+package org.apache.xpath.objects;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class represents, an object for XPath 3.1 data model sequences.
+ * 
+ * @author Mukul Gandhi <mukulg@apache.org>
+ * 
+ * @xsl.usage advanced
+ */
+public class ResultSequence extends XObject
+{
+    static final long serialVersionUID = -5736721866747906182L;
+    
+    // the underlying list object, storing items of this result sequence 
+    private List<XObject> rsList = new ArrayList<XObject>();
+    
+    // Class constructor.
+    public ResultSequence() {}
+    
+    public void add(XObject item) {
+        rsList.add(item);    
+    }
+    
+    public int size() {
+        return rsList.size();   
+    }
+    
+    public List<XObject> getResultSequenceItems() {
+        return rsList;   
+    }
+
+}
diff --git a/src/org/apache/xpath/res/XPATHErrorResources.java \
b/src/org/apache/xpath/res/XPATHErrorResources.java index a10c9a8b..75af7bcb 100644
--- a/src/org/apache/xpath/res/XPATHErrorResources.java
+++ b/src/org/apache/xpath/res/XPATHErrorResources.java
@@ -230,6 +230,8 @@ public static final String ER_IGNORABLE_WHITESPACE_NOT_HANDLED =
 	 "ER_FASTSTRINGBUFFER_CANNOT_BE_NULL";
    /**  2 or 3   */
   public static final String ER_TWO_OR_THREE = "ER_TWO_OR_THREE";
+  /**  1, 2 or 3   */
+  public static final String ER_ONE_TWO_OR_THREE = "ER_ONE_TWO_OR_THREE";
   /**  3 or 4   */
   public static final String ER_THREE_OR_FOUR = "ER_THREE_OR_FOUR";
    /** Variable accessed before it is bound! */
@@ -623,6 +625,9 @@ public static final String ER_IGNORABLE_WHITESPACE_NOT_HANDLED =
   { ER_TWO_OR_THREE,
        "2 or 3"},
   
+  { ER_ONE_TWO_OR_THREE,
+       "1, 2 or 3"},
+  
   { ER_THREE_OR_FOUR,
        "3 or 4"},
 


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


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic