Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible parameterize a compiled Java XPath expression ala PreparedStatement style semantics?

Is it possible either with the stock JAX-P xpath expression engine or another compliant engine to compile an xpath expression that would allow for parametrization?

I'm looking to see if is if there is an API that would allow a developer to set placeholders within a compiled xpath and replace those values at run time.

Any insight on this as to whether or not it is possible and if there are caveats, pitfalls, or just plain "don't do that" type advice would be greatly appreciated.

(Note I corrected a "crossing of the streams" ... was having a conversation with a coworker with regard to xpath & regular expressions ... just happened to get mentally tongue tied ... sorry for the confusion)

like image 603
Dave G Avatar asked Jul 19 '11 15:07

Dave G


People also ask

What is XPath in Java?

What is XPath? XPath is a major element in the XSLT standard. XPath can be used to navigate through elements and attributes in an XML document. XPath stands for XML Path Language. XPath uses "path like" syntax to identify and navigate nodes in an XML document.

What does XPath evaluate return?

expression - The XPath expression. source - The InputSource of the document to evaluate over. Returns: The String that is the result of evaluating the expression and converting the result to a String .

What is XPath in API?

The XPath language provides a simple, concise syntax for selecting nodes from an XML document. XPath also provides rules for converting a node in an XML document object model (DOM) tree to a boolean, double, or string value.

Is XPathExpression thread safe?

An XPath expression is not thread-safe and not reentrant. In other words, it is the application's responsibility to make sure that one XPathExpression object is not used from more than one thread at any given time, and while the evaluate method is invoked, applications may not recursively call the evaluate method.


1 Answers

Here's a very simple implementation of javax.xml.xpath.XPathVariableResolver

import java.util.HashMap;
import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.xpath.XPathVariableResolver;

public class SimpleVariableResolver implements XPathVariableResolver {

    private static final Map<QName, Object> vars = 
        new HashMap<QName, Object>();

    public void addVariable(QName name, Object value) {
        vars.put(name, value);
    }

    public Object resolveVariable(QName name) {
        return vars.get(name);
    }

}

Use it like this:

public static void main(String[] args) throws ParserConfigurationException,
        SAXException, IOException, XPathExpressionException {

    DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = domFactory.newDocumentBuilder();
    Document doc = builder.parse("workbook.xml");

    XPath xpath = XPathFactory.newInstance().newXPath();
    SimpleVariableResolver resolver = new SimpleVariableResolver();
    resolver.addVariable(new QName(null, "id"), 2);
    xpath.setXPathVariableResolver(resolver);
    XPathExpression expr = xpath.compile("/root/element[@id=$id]");
    Object result = expr.evaluate(doc, XPathConstants.NODESET);

    NodeList nodes = (NodeList) result;
    for (int i = 0; i < nodes.getLength(); i++) {
        System.out.println(nodes.item(i).getTextContent());
    }
}

On this document:

<root>
    <element id="1">one</element>
    <element id="2">two</element>
    <element id="3">three</element>
</root>

Output:

two
like image 99
Wayne Avatar answered Sep 19 '22 16:09

Wayne