/* GNU GENERAL LICENSE Copyright (C) 2006 The Lobo Project. Copyright (C) 2014 - 2017 Lobo Evolution This program 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 verion 3 of the License, or (at your option) any later version. This program 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. See the GNU General License for more details. You should have received a copy of the GNU General Public along with this program. If not, see <http://www.gnu.org/licenses/>. Contact info: lobochief@users.sourceforge.net; ivan.difrancesco@yahoo.it */ package org.lobobrowser.xpath; import java.io.StringWriter; import java.util.Properties; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import org.lobobrowser.xpath.function.XPathFunctionResolverImpl; import org.w3c.dom.Document; import org.w3c.dom.Node; /** * <p> * Various utilities for working with XPath. This class uses a static XPath * object for most of it's work. This XPath object is preconfigured to use the * extended XPath functions of the org.lobobrowser.http package. * </p> * * @author rbair */ public class XPathUtils { /** The Constant logger. */ private static final Logger logger = LogManager .getLogger(XPathUtils.class); /** The Constant xpath. */ private static final XPath xpath; /** The Constant functionResolver. */ private static final XPathFunctionResolverImpl functionResolver; static { xpath = XPathFactory.newInstance().newXPath(); functionResolver = new XPathFunctionResolverImpl(); xpath.setNamespaceContext(functionResolver); xpath.setXPathFunctionResolver(functionResolver); } /** * Instantiates a new x path utils. */ private XPathUtils() { } /** * Returns a {@link SimpleNodeList} containing all the nodes that match the * given expression when executed on the given node (as opposed to the dom * as a whole). * * @param expression * an XPath expression * @param node * the contextual node * @return SimpleNodeList containing the results from the expression. This * will never be null, but may contain no results. * @throws XPathExpressionException * the x path expression exception */ /* * public synchronized static NodeList getElements(String expression, Node * node) throws XPathExpressionException {NodeList nodes = new * DOMNodeListImpl((Collection)xpath.evaluate(expression, node, * XPathConstants.NODESET)); return nodes;} */ /** * Returns a Node matching the given expression. If more than one node * matches, the return value is undefined. * * @param expression * an XPath expression * @param node * the contextual node * @return Node. May be null. * @throws XPathExpressionException * if the expression does not parse */ public synchronized static Node getElement(String expression, Node node) throws XPathExpressionException { Node n = (Node) xpath.evaluate(expression, node, XPathConstants.NODE); return n; } /** * Returns the text content of the Node matching the given expression. If * more than one node matches, the return value is undefined. * * @param expression * an XPath expression * @param node * the contextual node * @return text content of the selected Node. May be null. * @throws XPathExpressionException * the x path expression exception */ public synchronized static String getString(String expression, Node node) throws XPathExpressionException { Node n = (Node) xpath.evaluate(expression, node, XPathConstants.NODE); return n == null ? null : n.getTextContent(); } /** * Gets the string. * * @param expression * the expression * @param node * the node * @param namespace * the namespace * @param namespacePrefix * the namespace prefix * @return the string * @throws XPathExpressionException * the x path expression exception */ public synchronized static String getString(String expression, Node node, String namespace, String namespacePrefix) throws XPathExpressionException { functionResolver.addNamespaceMapping(namespacePrefix, namespace); Node n = (Node) xpath.evaluate(expression, node, XPathConstants.NODE); functionResolver.removeNamespaceMapping(namespacePrefix); return n == null ? null : n.getTextContent(); } /** * Returns a {@link SimpleNodeList} containing all the nodes that match the * given expression when executed on the given node (as opposed to the dom * as a whole). * * @param expression * an XPath expression * @param node * the contextual node * @return SimpleNodeList containing the results from the expression. This * will never be null, but may contain no results. * @throws XPathExpressionException * the x path expression exception */ /* * public synchronized static NodeList getElements(XPathExpression * expression, Node node) throws XPathExpressionException {NodeList nodes = * new DOMNodeListImpl((Collection)expression.evaluate(node, * XPathConstants.NODESET)); return nodes;} */ /** * Returns a Node matching the given expression. If more than one node * matches, the return value is undefined. * * @param expression * an XPath expression * @param node * the contextual node * @return Node. May be null. * @throws XPathExpressionException * if the expression does not parse */ public synchronized static Node getElement(XPathExpression expression, Node node) throws XPathExpressionException { Node n = (Node) expression.evaluate(node, XPathConstants.NODE); return n; } /** * Returns the text content of the Node matching the given expression. If * more than one node matches, the return value is undefined. * * @param expression * an XPath expression * @param node * the contextual node * @return text content of the selected Node. May be null. * @throws XPathExpressionException * the x path expression exception */ public synchronized static String getString(XPathExpression expression, Node node) throws XPathExpressionException { Node n = (Node) expression.evaluate(node, XPathConstants.NODE); return n == null ? null : n.getTextContent(); } /** * Compiles the given expression, using the internal XPath instance of this * class and returns the XPathExpression. * * @param expression * The XPath expression to compile * @return the compiled XPathExpression * @throws XPathExpressionException * for a malformed XPath expression */ public synchronized static XPathExpression compile(String expression) throws XPathExpressionException { return xpath.compile(expression); } /** * Exports this DOM as a String. * * @param dom * the dom * @return the string */ public static String toXML(Document dom) { return toXML(dom, null); } /** * To xml. * * @param dom * the dom * @param outputProperties * the output properties * @return the string */ public static String toXML(Document dom, Properties outputProperties) { try { DOMSource source = new DOMSource(dom); StringWriter writer = new StringWriter(); StreamResult result = new StreamResult(writer); Transformer tx = TransformerFactory.newInstance().newTransformer(); if (outputProperties != null) { tx.setOutputProperties(outputProperties); } tx.transform(source, result); String s = writer.toString(); writer.close(); return s; } catch (Exception e) { logger.error(e.getMessage()); return null; } } }