xpath.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 405 行

JAVA
405
字号
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the *   Free SoftwareFoundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Scott Ferguson */package com.caucho.xpath;import com.caucho.loader.EnvironmentLocal;import com.caucho.log.Log;import com.caucho.util.LruCache;import com.caucho.xpath.pattern.AbstractPattern;import com.caucho.xpath.pattern.FromContext;import org.w3c.dom.Node;import java.util.Iterator;import java.util.logging.Level;import java.util.logging.Logger;/** * Public facade for selecting nodes and creating match patterns. * * <p>Applications can select nodes directly from the XPath facade.   * For example, * <code><pre> * Node verse = XPath.find("chapter/verse", node); * </pre></code> * * <p>For greater efficiency, applications can also precompile the  * match patterns. * <code><pre> * Pattern pattern = XPath.parseSelect("chapter/verse"); * Node verse = pattern.find(node); * </pre></code> * * <p>XPath can also return values based on XPath expressions, following * the XPath expression syntax.  Applications can use the expressions for * the equivalent of xsl:value-of * <code><pre> * Expr expr = XPath.parseExpr("chapter/verse/@id + 1"); * double value = expr.evalNumber(node); * </pre></code> * * <p>To support the XPath pattern variables, XPath uses an environment * object.  Most applications will not need to use it.  */public class XPath {  private static final Logger log    = Logger.getLogger(XPath.class.getName());  private static EnvironmentLocal<LruCache<String,Pattern>> _matchCache    = new EnvironmentLocal<LruCache<String,Pattern>>();    private static EnvironmentLocal<LruCache<String,Pattern>> _selectCache    = new EnvironmentLocal<LruCache<String,Pattern>>();    private static EnvironmentLocal<LruCache<String,Expr>> _exprCache    = new EnvironmentLocal<LruCache<String,Expr>>();  private XPath()  {  }  /**   * Finds a node based on an XPath pattern.  The pattern is relative   * to the node so <code>XPath.find("child", node)</code> will find children,   * not grandchildren.   *   * @param query XPath select pattern.   * @param node XML node to start searching from.   * @return The first matching node in document order.   */  public static Node find(String query, Node node)    throws XPathException  {    Pattern pattern = parseSelect(query);    return (Node) pattern.find(node);  }  /**   * Selects all node matching an XPath pattern   *   * @param query XPath select pattern.   * @param node XML node to start searching from.   * @return An iterator of nodes matching the pattern.   */  public static Iterator select(String query, Node node)    throws XPathException  {    Pattern pattern = parseSelect(query);    return pattern.select(node);  }  /**   * Create a node selection pattern.  The pattern matches relative   * to the current node.   *   * @param query XPath select pattern.   * @return a pattern that can later select nodes.   */  public static Pattern parseSelect(String query)    throws XPathParseException  {    LruCache<String,Pattern> cache = _selectCache.get();    if (cache == null)      cache = new LruCache<String,Pattern>(128);        Pattern pattern = cache.get(query);    if (pattern == null) {      pattern = parseSelect(query, null);      cache.put(query, pattern);    }    return pattern;  }  /**   * Create a node selection pattern.  The pattern matches relative   * to the current node.   *   * <p>XSLT uses this version of parseSelect for proper namespace   * matching.   *   * @param query XPath select pattern.   * @param namespace the appropriate namespace mappings   *   * @return a pattern that can later select nodes.   */  public static Pattern parseSelect(String query, NamespaceContext namespace)    throws XPathParseException  {    XPathParser parser = new XPathParser(query, namespace);    AbstractPattern pattern = parser.parseSelect();    if (log.isLoggable(Level.FINER))      log.finest("select: " + pattern);    return new Pattern(pattern);  }  /**   * Create a node match pattern.  Match patterns are intended to test   * if a node matches the pattern.  They do not work well for finding or   * selecting patterns.  Essentially, a match pattern of 'foo[@bar]' is   * equivalent to a select pattern of '//foo[@bar]', but with less overhead.   *   * @param query XPath match pattern.   * @return a pattern that can later be used for isMatch.   */  public static Pattern parseMatch(String query)    throws XPathParseException  {    LruCache<String,Pattern> cache = _matchCache.get();    if (cache == null)      cache = new LruCache<String,Pattern>(128);        Pattern pattern = cache.get(query);    if (pattern == null) {      pattern = parseMatch(query, null);      cache.put(query, pattern);    }    return pattern;  }  /**   * Create a node match pattern.  Match patterns are intended to test   * if a node matches the pattern.  They do not work well for finding or   * selecting patterns.  Essentially, a match pattern of 'foo[@bar]' is   * equivalent to a select pattern of '//foo[@bar]', but with less overhead.   *   * @param query XPath match pattern.   * @param namespace the appropriate namespace mappings.   *   * @return a pattern that can later be used for isMatch.   */  public static Pattern parseMatch(String query, NamespaceContext namespace)    throws XPathParseException  {    XPathParser parser = new XPathParser(query, namespace);    AbstractPattern pattern = parser.parseMatch();    if (log.isLoggable(Level.FINER))      log.finest("match: " + pattern);    return new Pattern(pattern);  }  /**   * Evaluates an XPath expression, returning a string.  evalString works   * like the XSL <code>value-of</code> element.   *   * <p>For example, to get the value of an attribute use:   *   * <code><pre>   * String value = XPath.evalString("@id", node);   * </pre></code>   *   * @param query XPath expression   * @param node the node context   *   * @return the string result of the expression.   */  public static String evalString(String query, Node node)    throws XPathException  {    Expr expr = parseExpr(query);    return expr.evalString(node);  }  /**   * Evaluates an XPath expression, returning a double.   *   * @param query XPath expression   * @param node the node context   *   * @return the number result of the expression.   */  public static double evalNumber(String query, Node node)    throws XPathException  {    Expr expr = parseExpr(query);    return expr.evalNumber(node);  }  /**   * Evaluates an XPath expression, returning a boolean.   *   * @param query XPath expression   * @param node the node context   *   * @return the boolean result of the expression.   */  public static boolean evalBoolean(String query, Node node)    throws XPathException  {    Expr expr = parseExpr(query);    return expr.evalBoolean(node);  }  /**   * Evaluates an XPath expression, returning an object   *   * @param query XPath expression   * @param node the node context   *   * @return the result of the expression.   */  public static Object evalObject(String query, Node node)    throws XPathException  {    Expr expr = parseExpr(query);    return expr.evalObject(node);  }  /**   * Parses an XPath expression for later evaluation.   *   * @param query XPath expression   * @return the result of the expression.   */  public static Expr parseExpr(String query)    throws XPathParseException  {    LruCache<String,Expr> cache = _exprCache.get();    if (cache == null) {      cache = new LruCache<String,Expr>(128);      _exprCache.set(cache);    }        Expr expr = cache.get(query);    if (expr == null) {      expr = parseExpr(query, null);      cache.put(query, expr);    }    return expr;  }  /**   * Parses an XPath expression for later evaluation.   *   * @param query XPath expression   * @param namespace namespace context   *   * @return the compiled expression   */  public static Expr parseExpr(String query, NamespaceContext namespace)    throws XPathParseException  {    XPathParser parser = new XPathParser(query, namespace);    Expr expr = parser.parseExpr();    if (log.isLoggable(Level.FINER))      log.finest("expr: " + expr);    return expr;  }  /**   * Parses an XPath expression for later evaluation.   *   * @param query XPath expression   * @param namespace namespace context   * @param nodeList containing nodeList pattern   *   * @return the compiled expression   */  public static Expr parseExpr(String query, NamespaceContext namespace,			       AbstractPattern nodeList)    throws XPathParseException  {    XPathParser parser = new XPathParser(query, namespace);    Expr expr = parser.parseExpr(new FromContext(), nodeList);    if (expr != null)      expr.setListContext(nodeList);    if (log.isLoggable(Level.FINER))      log.finest("expr: " + expr);    return expr;  }  /**   * Creates a new variable environment.   */  public static Env createEnv()  {    return Env.create();  }  /**   * Creates a new variable environment based on an old environment.   *   * <p>This lets environments share globals even through function calls.   */  public static Env createEnv(Env global)  {    Env env = Env.create();    env.init(global);    return env;  }  /**   * Creates a new variable environment based on an old environment.   *   * <p>This lets environments share globals even through function calls.   */  public static Env createCall(Env parent)  {    Env env = Env.create();    env.initMacro(parent);    return env;  }  /**   * Free an environment.   */  public static void freeEnv(Env env)  {    // env.free();  }}

⌨️ 快捷键说明

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