2

I have researched and researched but nothing seems to work. Say I want an xpath with the text "Tony's Computer". I cannot do the following:

//*[contains(text(), 'Tony's Computer')]

for obvious reasons, as the ' between the y and s unquotes the text. But nor does this work:

//*[contains(text(), 'Tony\'s Computer')]

also

//*[contains(text(), 'Tony''s Computer')]

Is there a way to escape the apostrophe? I cannot find anything. The best I can do is the following with Java (assume textToLookFor has the text to look for):

        String[] fields = textToLookFor.split("'");
        String textx = "";
        for (int indx = 0; indx < fields.length; indx++) {
            String stext = fields[indx];
            String cont = "contains(text(),'" + stext + "') ";
            if (!textx.isEmpty()) {
                textx += " and ";
            }
            textx += cont;
        }
        String xpath = "//*[" + textx + "]";

which basically does a

//*[contains(text(),'Tony') and contains(text(), 's Computer')]

which is I suppose good enough. However, it is not an exact match. It could find "Tony and Bob's Computer" for instance.

Has anyone else had success doing this? I cannot find any other solutions. By the way, when I find the element I can say String displayed = ele.getText(); and then check that displayed.contains(textToLookFor).

In this case I first need to do a textToLookFor = textToLookFor.replaceAll("\"", "\\\""); which escapes any double quotes.

Tony
  • 1,127
  • 1
  • 18
  • 29
  • They suggest using " instead of ', or using \' but that did not work for me. By "They" I meant the above possible duplicate ;-) – Tony Mar 16 '17 at 13:03
  • Are you using XPath 1.0? – Mads Hansen Mar 16 '17 at 13:56
  • @Tony you should've posted your code showing how you implement 'their' suggestion. How about : `String xpath = "//*[contains(.,\"Tony's Computer\")]";` ? – har07 Mar 17 '17 at 02:09

3 Answers3

2

I am assuming that you are using XPath 1.0. Have you tried using the entity &apos; in your XPath?

//*[contains(text(), 'Tony&apos;s Computer')]

Doubling the single apostrophe should work in XSLT 2.0. So, another option would be to use Saxon as your XPath engine and then use XPath 2.0, then the following would work:

//*[contains(text(), 'Tony''s Computer')]
Mads Hansen
  • 63,927
  • 12
  • 112
  • 147
  • We can't change the xpath engine. Well I would have to get IT's permission. I don't think I have tried the apos. I will try that tomorrow when I am back at work. – Tony Mar 23 '17 at 00:54
2
//*[contains(.,"Tony's Computer")]

Works for me. Use double quotes on outside of string.

Bill Hileman
  • 2,798
  • 2
  • 17
  • 24
1

Firstly, this depends a bit on your host language (in your case Java, for many other people XSLT), because you have to think not only about which characters are special in XPath, but which are special in your host language. The general rule is, write an expression that satisfies the XPath rules, then use host language escaping to satisfy the host language rules (for example, " becomes \" in Java). Host language escaping isn't going to help you get past the XPath rules, because by the time XPath sees the string, the host language escaping has gone.

XPath allows you to use either ' or " as your string delimiter, so if only one of these characters appears within the string, you can use the other as the delimiter: "Tony's Computer" or 'He said "boo!"'. With either of those, if you're in Java, you then replace " with \" (while if you're in XSLT, you replace " with &quot;).

XPath 2.0 also allows you to use the delimiting quote within the string literal by doubling it, which is useful if you need both kinds of quote in the same string: "He said, ""I can't""", or 'He said, "I can''t"' (Again, you then have to add the Java-level escaping.) This isn't possible in 1.0, but you can get around it by using concat(): concat("He said, ", '"', "I can't", '"').

Michael Kay
  • 156,231
  • 11
  • 92
  • 164
  • Yes I do escape the double quotes with \ (for instance "\"Tony's Computer\"". Maybe we are still using xpath 1.0? I also tried with backslashing the single quote (like contains(text(),'Tony\'s Computer')]. – Tony Mar 23 '17 at 00:52
  • If it's not working, then tell us what you are doing and how it fails. If it is working, then accept the answer. – Michael Kay Mar 23 '17 at 09:34