⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xpathparser.java

📁 java1.6众多例子参考
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed 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: XPathParser.java,v 1.2.4.1 2005/09/14 19:46:02 jeffsuttor Exp $ */package com.sun.org.apache.xpath.internal.compiler;import javax.xml.transform.ErrorListener;import javax.xml.transform.TransformerException;import com.sun.org.apache.xalan.internal.res.XSLMessages;import com.sun.org.apache.xml.internal.utils.PrefixResolver;import com.sun.org.apache.xpath.internal.XPathProcessorException;import com.sun.org.apache.xpath.internal.domapi.XPathStylesheetDOM3Exception;import com.sun.org.apache.xpath.internal.objects.XNumber;import com.sun.org.apache.xpath.internal.objects.XString;import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;/** * Tokenizes and parses XPath expressions. This should really be named * XPathParserImpl, and may be renamed in the future. * @xsl.usage general */public class XPathParser{	// %REVIEW% Is there a better way of doing this?	// Upside is minimum object churn. Downside is that we don't have a useful	// backtrace in the exception itself -- but we don't expect to need one.	static public final String CONTINUE_AFTER_FATAL_ERROR="CONTINUE_AFTER_FATAL_ERROR";  /**   * The XPath to be processed.   */  private OpMap m_ops;  /**   * The next token in the pattern.   */  transient String m_token;  /**   * The first char in m_token, the theory being that this   * is an optimization because we won't have to do charAt(0) as   * often.   */  transient char m_tokenChar = 0;  /**   * The position in the token queue is tracked by m_queueMark.   */  int m_queueMark = 0;  /**   * Results from checking FilterExpr syntax   */  protected final static int FILTER_MATCH_FAILED     = 0;  protected final static int FILTER_MATCH_PRIMARY    = 1;  protected final static int FILTER_MATCH_PREDICATES = 2;  /**   * The parser constructor.   */  public XPathParser(ErrorListener errorListener, javax.xml.transform.SourceLocator sourceLocator)  {    m_errorListener = errorListener;    m_sourceLocator = sourceLocator;  }  /**   * The prefix resolver to map prefixes to namespaces in the OpMap.   */  PrefixResolver m_namespaceContext;  /**   * Given an string, init an XPath object for selections,   * in order that a parse doesn't   * have to be done each time the expression is evaluated.   *    * @param compiler The compiler object.   * @param expression A string conforming to the XPath grammar.   * @param namespaceContext An object that is able to resolve prefixes in   * the XPath to namespaces.   *   * @throws javax.xml.transform.TransformerException   */  public void initXPath(          Compiler compiler, String expression, PrefixResolver namespaceContext)            throws javax.xml.transform.TransformerException  {    m_ops = compiler;    m_namespaceContext = namespaceContext;    m_functionTable = compiler.getFunctionTable();    Lexer lexer = new Lexer(compiler, namespaceContext, this);    lexer.tokenize(expression);    m_ops.setOp(0,OpCodes.OP_XPATH);    m_ops.setOp(OpMap.MAPINDEX_LENGTH,2);        	// Patch for Christine's gripe. She wants her errorHandler to return from	// a fatal error and continue trying to parse, rather than throwing an exception.	// Without the patch, that put us into an endless loop.	//	// %REVIEW% Is there a better way of doing this?	// %REVIEW% Are there any other cases which need the safety net?	// 	(and if so do we care right now, or should we rewrite the XPath	//	grammar engine and can fix it at that time?)	try {      nextToken();      Expr();      if (null != m_token)      {        String extraTokens = "";        while (null != m_token)        {          extraTokens += "'" + m_token + "'";          nextToken();          if (null != m_token)            extraTokens += ", ";        }        error(XPATHErrorResources.ER_EXTRA_ILLEGAL_TOKENS,              new Object[]{ extraTokens });  //"Extra illegal tokens: "+extraTokens);      }    }     catch (com.sun.org.apache.xpath.internal.XPathProcessorException e)    {	  if(CONTINUE_AFTER_FATAL_ERROR.equals(e.getMessage()))	  {		// What I _want_ to do is null out this XPath.		// I doubt this has the desired effect, but I'm not sure what else to do.		// %REVIEW%!!!		initXPath(compiler, "/..",  namespaceContext);	  }	  else		throw e;    }    compiler.shrink();  }  /**   * Given an string, init an XPath object for pattern matches,   * in order that a parse doesn't   * have to be done each time the expression is evaluated.   * @param compiler The XPath object to be initialized.   * @param expression A String representing the XPath.   * @param namespaceContext An object that is able to resolve prefixes in   * the XPath to namespaces.   *   * @throws javax.xml.transform.TransformerException   */  public void initMatchPattern(          Compiler compiler, String expression, PrefixResolver namespaceContext)            throws javax.xml.transform.TransformerException  {    m_ops = compiler;    m_namespaceContext = namespaceContext;    m_functionTable = compiler.getFunctionTable();    Lexer lexer = new Lexer(compiler, namespaceContext, this);    lexer.tokenize(expression);    m_ops.setOp(0, OpCodes.OP_MATCHPATTERN);    m_ops.setOp(OpMap.MAPINDEX_LENGTH, 2);    nextToken();    Pattern();    if (null != m_token)    {      String extraTokens = "";      while (null != m_token)      {        extraTokens += "'" + m_token + "'";        nextToken();        if (null != m_token)          extraTokens += ", ";      }      error(XPATHErrorResources.ER_EXTRA_ILLEGAL_TOKENS,            new Object[]{ extraTokens });  //"Extra illegal tokens: "+extraTokens);    }    // Terminate for safety.    m_ops.setOp(m_ops.getOp(OpMap.MAPINDEX_LENGTH), OpCodes.ENDOP);    m_ops.setOp(OpMap.MAPINDEX_LENGTH, m_ops.getOp(OpMap.MAPINDEX_LENGTH)+1);    m_ops.shrink();  }  /** The error listener where syntax errors are to be sent.   */  private ErrorListener m_errorListener;    /** The source location of the XPath. */  javax.xml.transform.SourceLocator m_sourceLocator;    /** The table contains build-in functions and customized functions */  private FunctionTable m_functionTable;  /**   * Allow an application to register an error event handler, where syntax    * errors will be sent.  If the error listener is not set, syntax errors    * will be sent to System.err.   *    * @param handler Reference to error listener where syntax errors will be    *                sent.   */  public void setErrorHandler(ErrorListener handler)  {    m_errorListener = handler;  }  /**   * Return the current error listener.   *   * @return The error listener, which should not normally be null, but may be.   */  public ErrorListener getErrorListener()  {    return m_errorListener;  }  /**   * Check whether m_token matches the target string.    *   * @param s A string reference or null.   *   * @return If m_token is null, returns false (or true if s is also null), or    * return true if the current token matches the string, else false.   */  final boolean tokenIs(String s)  {    return (m_token != null) ? (m_token.equals(s)) : (s == null);  }  /**   * Check whether m_tokenChar==c.    *   * @param c A character to be tested.   *   * @return If m_token is null, returns false, or return true if c matches    *         the current token.   */  final boolean tokenIs(char c)  {    return (m_token != null) ? (m_tokenChar == c) : false;  }  /**   * Look ahead of the current token in order to   * make a branching decision.   *   * @param c the character to be tested for.   * @param n number of tokens to look ahead.  Must be   * greater than 1.   *   * @return true if the next token matches the character argument.   */  final boolean lookahead(char c, int n)  {    int pos = (m_queueMark + n);    boolean b;    if ((pos <= m_ops.getTokenQueueSize()) && (pos > 0)            && (m_ops.getTokenQueueSize() != 0))    {      String tok = ((String) m_ops.m_tokenQueue.elementAt(pos - 1));      b = (tok.length() == 1) ? (tok.charAt(0) == c) : false;    }    else    {      b = false;    }    return b;  }  /**   * Look behind the first character of the current token in order to   * make a branching decision.   *    * @param c the character to compare it to.   * @param n number of tokens to look behind.  Must be   * greater than 1.  Note that the look behind terminates   * at either the beginning of the string or on a '|'   * character.  Because of this, this method should only   * be used for pattern matching.   *   * @return true if the token behind the current token matches the character    *         argument.   */  private final boolean lookbehind(char c, int n)  {    boolean isToken;    int lookBehindPos = m_queueMark - (n + 1);    if (lookBehindPos >= 0)    {      String lookbehind = (String) m_ops.m_tokenQueue.elementAt(lookBehindPos);      if (lookbehind.length() == 1)      {        char c0 = (lookbehind == null) ? '|' : lookbehind.charAt(0);        isToken = (c0 == '|') ? false : (c0 == c);      }      else      {        isToken = false;      }    }    else    {      isToken = false;    }    return isToken;  }  /**   * look behind the current token in order to   * see if there is a useable token.   *    * @param n number of tokens to look behind.  Must be   * greater than 1.  Note that the look behind terminates   * at either the beginning of the string or on a '|'   * character.  Because of this, this method should only   * be used for pattern matching.   *    * @return true if look behind has a token, false otherwise.   */  private final boolean lookbehindHasToken(int n)  {    boolean hasToken;    if ((m_queueMark - n) > 0)    {      String lookbehind = (String) m_ops.m_tokenQueue.elementAt(m_queueMark - (n - 1));      char c0 = (lookbehind == null) ? '|' : lookbehind.charAt(0);      hasToken = (c0 == '|') ? false : true;    }    else    {      hasToken = false;    }    return hasToken;  }  /**   * Look ahead of the current token in order to   * make a branching decision.   *    * @param s the string to compare it to.   * @param n number of tokens to lookahead.  Must be   * greater than 1.   *   * @return true if the token behind the current token matches the string    *         argument.   */  private final boolean lookahead(String s, int n)  {    boolean isToken;    if ((m_queueMark + n) <= m_ops.getTokenQueueSize())    {      String lookahead = (String) m_ops.m_tokenQueue.elementAt(m_queueMark + (n - 1));      isToken = (lookahead != null) ? lookahead.equals(s) : (s == null);    }    else    {      isToken = (null == s);    }    return isToken;  }  /**   * Retrieve the next token from the command and   * store it in m_token string.   */  private final void nextToken()  {    if (m_queueMark < m_ops.getTokenQueueSize())    {      m_token = (String) m_ops.m_tokenQueue.elementAt(m_queueMark++);      m_tokenChar = m_token.charAt(0);    }    else    {      m_token = null;      m_tokenChar = 0;    }  }  /**   * Retrieve a token relative to the current token.   *    * @param i Position relative to current token.   *   * @return The string at the given index, or null if the index is out    *         of range.   */  private final String getTokenRelative(int i)  {    String tok;    int relative = m_queueMark + i;    if ((relative > 0) && (relative < m_ops.getTokenQueueSize()))    {      tok = (String) m_ops.m_tokenQueue.elementAt(relative);    }    else    {      tok = null;    }    return tok;  }  /**   * Retrieve the previous token from the command and   * store it in m_token string.   */  private final void prevToken()  {    if (m_queueMark > 0)    {      m_queueMark--;      m_token = (String) m_ops.m_tokenQueue.elementAt(m_queueMark);      m_tokenChar = m_token.charAt(0);    }    else    {      m_token = null;      m_tokenChar = 0;    }  }  /**

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -