I have an XPath query that looks like this, with both single and double quotes. How do I escape the apostrophe properly so that the query works?
I tried:
"//li[text()='Frank's car']"
but it doesn't seem to do it for me.
Any ideas?
"//li[text()='Frank's car']"
XPath doesn’t have any way of escaping special characters, so this is a little tricky. A solution in this specific case would be to use double quotes instead of single quotes in the XPath expression:
text()="Frank's car"
If you did this, you’d have to escape the quotes from Ruby if you used double quotes around the whole expression:
"//li[text()=\"Frank's car\"]"
You could use single quotes here if you aren’t doing any interpolation, and then escape the single quote:
'//li[text()="Frank\'s car"]'
A better option would perhaps be to make use of Ruby’s flexible quoting, so that none of the quotes would need escaping ,e.g.:
%{//li[text()="Frank's car"]}
Note that all the examples here doing escaping in Ruby, so that the string that reaches the XPath processor is //li[text()="Frank's car"]
.
The more general case, when the text is variable that could contain single or double quotes is more difficult. XPath’s string literals can’t contain both types of quotes; you need to construct the string using the XPath concat
function.
For example, if you wanted to match the string "That's mine", he said.
, you would need to do something like:
text()=concat('"That', "'", 's mine", he said.')
And then you’d have to escape the quotes from Ruby (using %{}
would be easiest).
I found another question on SO dealing with this issue in C#, and a thread on the Nokogiri mailing list, both of which might be worth looking at if you need to take this further.