Java XPath cache query

See post in french.

When we want to process multiple identical XPath query on XML document, in a optimized way, we have to compile only once XPath query and to store it to be able to use it later.

Le following singleton Java class manage in a simple way cached XPath query:


package com.devbypractice;

import java.util.HashMap;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class XPathProcessor
{
 // Singleton instance
 //
 protected static XPathProcessor _instance = new XPathProcessor();

 // XPath expressions hashmap cache
 //
 protected HashMap<String, XPathExpression> _hmXPathExpressions = new HashMap<String, XPathExpression>();

 // Xpath processing object
 //
 XPath xPath = XPathFactory.newInstance().newXPath();

 /**
 * Private constructor
 */
 protected XPathProcessor() {}

 /**
 * @return Singleton instance
 */
 public static XPathProcessor getInstance()
 {
 return _instance;
 }

 /**
 * Get XPath compiled expression from cache
 *
 * @param sXpathExpress XPath string
 * @return XPath compiled expression
 * @throws Exception
 */
 protected  XPathExpression getExpression(String sXpathExpress) throws Exception
 {
 XPathExpression expression;
 if (_hmXPathExpressions.containsKey(sXpathExpress)) {
 expression = _hmXPathExpressions.get(sXpathExpress);
 }
 else {
 expression = xPath.compile(sXpathExpress);
 _hmXPathExpressions.put(sXpathExpress, expression);
 }

 return expression;
 }

 /**
 * Evaluate XPath expression on Xml with single result
 * @param sXpathExpress XPath string
 * @param xml XML node
 * @return Single result of XPath evaluation
 * @throws Exception
 */
 public String Evaluate(String sXpathExpress, Node xml) throws Exception
 {
 XPathExpression expr = getExpression(sXpathExpress);

 return expr.evaluate(xml);
 }

 /**
 * Evaluate XPath expression on Xml with multiple results
 * @param sXpathExpress XPath string
 * @param xml XML node
 * @return Multiple results of XPath evaluation
 * @throws Exception
 */
public NodeList EvaluateMutli(String sXpathExpress, Node xml) throws Exception
 {
 XPathExpression expr = getExpression(sXpathExpress);

 return (NodeList)expr.evaluate(xml, XPathConstants.NODESET);
 }

}

Usage:

  • XPathProcessor.getInstance().Evaluate(“/xpath1″, xmlNode1)
  • XPathProcessor.getInstance().EvaluateMulti(“/xpath2″, xmlNode2)

Tags: , ,

One Response to “Java XPath cache query”

  1. Alex says:

    Should be noted that XPathExpression is not thread safe. Approach you described will not work without synchronization, pooling, etc.
    http://download.oracle.com/javase/6/docs/api/javax/xml/xpath/XPathExpression.html

Leave a Reply