Reputation: 53
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
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
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