3

Here is the code I currently have:

Document document2 = builder.parse(new FileInputStream("C:path to xml file.xml"));
Node theNode2 = (Node) xpath.evaluate("//*[@name='**variable here**']", document2, XPathConstants.NODE);

Where the code says "variable here", is it possible to search the XML file with a variable? I've only been able to hardcode in the thing I'm searching for so far ie :

("//*[@name='happy']", document2, XPathConstants.NODE);

2 Answers 2

6

You need to create an instance of XPathVariableResolver and attach it to your XPath instance. There are unfortunately no standard implementations of this interface provided by default but it only contains one method so it's easy enough to implement yourself:

final Map<String, Object> variables = new HashMap<String, Object>();
XPathVariableResolver varResolver = new XPathVariableResolver() {
  public Object resolveVariable(QName name) {
    // for simplicity, ignore namespaces
    return variables.get(name.getLocalPart());
  }
};
xpath.setXPathVariableResolver(varResolver);

With this in place you can now create variable bindings and refer to them in the XPath using $var syntax:

variables.put("theName", "happy");
Node theNode2 = (Node) xpath.evaluate("//*[@name=$theName]", document2, XPathConstants.NODE);

This is much safer than trying to build up the XPath expression by concatenating different strings together, particularly if the value you want to use for theName comes from an untrusted source (this is the XPath equivalent of an SQL injection vulnerability).

For XPath there's the additional complication that while you can delimit a string literal with either single or double quotes there is no escaping mechanism, so it is impossible to have a single string literal in XPath that includes both single and double quote characters (you have to use a workaround like concat('"', "'")). The variable resolver approach can handle this situation no problem:

variables.put("theName", "John \"The Boss\" O'Brien"); // escape " from Java
Node theNode2 = (Node) xpath.evaluate("//*[@name=$theName]", document2, XPathConstants.NODE);

Furthermore, now the actual XPath expression is a constant you can compile it once and then execute it multiple times against different variable values if you need to, rather than recompile it every time:

XPathExpression expr = xpath.compile("//*[@name=$theName]");
// look for @name='name 1'
variables.put("theName", "name 1");
Node node1 = expr.evaluate(document2, XPathConstants.NODE);
// look for @name='name 2' in the same document
variables.put("theName", "name 2");
Node node2 = expr.evaluate(document2, XPathConstants.NODE);
Sign up to request clarification or add additional context in comments.

Comments

-2

Your question is not very clear but i think what you want to be able to do is search for something but not hardcode this variable name?

String variable = "variable name";
Document document2 = builder.parse(new FileInputStream("C:path to xml file.xml"));
    Node theNode2 = (Node) xpath.evaluate("//*[@name='" + variable+"']", document2, XPathConstants.NODE);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.