amey pawar
amey pawar

Reputation: 53

Invalid XPath expression exception due to presence of apostrophe in name

I am getting Invalid Xpath Exception for following code.

current.Name = current.Name.replace("'", "\'");
System.out.println(current.Name );
String xp1 = "//page[@name='"+current.Name+"']" ;
Element n = (Element) oDocument.selectSingleNode(xp1+"/Body/contents");

Exception occurs when the string in current.name has an apostrophe in it

current.name: "Répartition par secteur d'activité"

Error Message

Upvotes: 5

Views: 11316

Answers (2)

Ian Roberts
Ian Roberts

Reputation: 122364

In XPath expressions strings can be delimited with single or double quotes. You can include single quote characters within double quoted strings or double quote characters in single quoted strings, but not vice versa - in XPath 1.0 there is no escaping mechanism so it's impossible to have both single and double quote characters within the same string literal, you have to use a trick like

concat('Strings can use "double" quotes', " or 'single' quotes")

Generally you should avoid constructing XPath expressions using string concatenation, instead use a constant XPath expression that references a variable, and pass in the variable value using the mechanism your XPath library provides. This is analagous to using a JDBC PreparedStatement with parameter placeholders rather than concatenating strings of SQL. Your comment suggests you're using dom4j, the mechanism for injecting variable values in that library is:

import org.jaxen.SimpleVariableContext;
import org.dom4j.XPath;

XPath xpath = oDocument.createXPath("//page[@name=$targetName]/Body/contents");
SimpleVariableContext ctx = new SimpleVariableContext();
xpath.setVariableContext(ctx);
ctx.setVariableValue("targetName", current.Name);
Element n = (Element)xpath.selectSingleNode(oDocument);

You can re-use the same VariableContext with many different XPath objects. Since it does not pass the current.Name value through the XPath parser, this approach will work correctly in all cases, even when the value contains both types of quote character.

Upvotes: 1

beny23
beny23

Reputation: 35008

You can escape the quote by doubling it:

current.Name = current.Name.replace("'", "''");

EDIT:

For Xpath 1.0, you could try the following:

String xp1 = "//page[@name=\""+current.Name+"\"]" ;

I.e. Use double quotes instead of single quotes to delimit the name (though that means you won't be able to search for strings with a double quote.

Note also, for the second solution you won't need to replace the quotes.

Upvotes: 3

Related Questions