All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.caucho.xpath.XPath Maven / Gradle / Ivy

There is a newer version: 4.0.66
Show newest version
/*
 * Copyright (c) 1998-2018 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.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.
 *
 * 

Applications can select nodes directly from the XPath facade. * For example, *

 * Node verse = XPath.find("chapter/verse", node);
 * 
* *

For greater efficiency, applications can also precompile the * match patterns. *

 * Pattern pattern = XPath.parseSelect("chapter/verse");
 * Node verse = pattern.find(node);
 * 
* *

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 *

 * Expr expr = XPath.parseExpr("chapter/verse/@id + 1");
 * double value = expr.evalNumber(node);
 * 
* *

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> _matchCache = new EnvironmentLocal>(); private static EnvironmentLocal> _selectCache = new EnvironmentLocal>(); private static EnvironmentLocal> _exprCache = new EnvironmentLocal>(); private XPath() { } /** * Finds a node based on an XPath pattern. The pattern is relative * to the node so XPath.find("child", node) 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 cache = _selectCache.get(); if (cache == null) cache = new LruCache(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. * *

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 cache = _matchCache.get(); if (cache == null) cache = new LruCache(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 value-of element. * *

For example, to get the value of an attribute use: * *

   * String value = XPath.evalString("@id", node);
   * 
* * @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 cache = _exprCache.get(); if (cache == null) { cache = new LruCache(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. * *

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. * *

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(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy