Apostrophe (') in Xpath Query

How to use apostrophe (') in xpath while finding element using webdriver?

Use the xpath as shown below:

driver.findElements(By.xpath("//input[contains(@text,\"WE'd\")]"));

Hope this helps.

How to write xpath in selenium for a text that contains Apostrophe (')

Although the escape sequence for a single quote (') in Xml is ', there's a limitation in XPath 1.0 preventing ' from being used directly in a path.

Also, as it stands, your question asks for any element with a text attribute containing the search string, e.g.

 <node text="Please upload this owner's ID:" />

Assuming there are no other text attributes with strings containing those two phases, a hacky approximation to the search would be:

//*[contains(@text, 'Please upload this owner') and contains(@text, 's ID:')]

If however you meant that the element's text() content needed to match (i.e. not a text attribute):

 <node>Please upload this owner's ID</node>

Then the same hack would be:

//*[contains(text(), 'Please upload this owner') and contains(text(), 's ID:')]

Apostrophe (') in XPath query

This is surprisingly difficult to do.

Take a look at the XPath Recommendation, and you'll see that it defines a literal as:

Literal ::=   '"' [^"]* '"' 
| "'" [^']* "'"

Which is to say, string literals in XPath expressions can contain apostrophes or double quotes but not both.

You can't use escaping to get around this. A literal like this:

'Some'Value'

will match this XML text:

Some&apos;Value

This does mean that it's possible for there to be a piece of XML text that you can't generate an XPath literal to match, e.g.:

<elm att=""&apos"/>

But that doesn't mean it's impossible to match that text with XPath, it's just tricky. In any case where the value you're trying to match contains both single and double quotes, you can construct an expression that uses concat to produce the text that it's going to match:

elm[@att=concat('"', "'")]

So that leads us to this, which is a lot more complicated than I'd like it to be:

/// <summary>
/// Produce an XPath literal equal to the value if possible; if not, produce
/// an XPath expression that will match the value.
///
/// Note that this function will produce very long XPath expressions if a value
/// contains a long run of double quotes.
/// </summary>
/// <param name="value">The value to match.</param>
/// <returns>If the value contains only single or double quotes, an XPath
/// literal equal to the value. If it contains both, an XPath expression,
/// using concat(), that evaluates to the value.</returns>
static string XPathLiteral(string value)
{
// if the value contains only single or double quotes, construct
// an XPath literal
if (!value.Contains("\""))
{
return "\"" + value + "\"";
}
if (!value.Contains("'"))
{
return "'" + value + "'";
}

// if the value contains both single and double quotes, construct an
// expression that concatenates all non-double-quote substrings with
// the quotes, e.g.:
//
// concat("foo", '"', "bar")
StringBuilder sb = new StringBuilder();
sb.Append("concat(");
string[] substrings = value.Split('\"');
for (int i = 0; i < substrings.Length; i++ )
{
bool needComma = (i>0);
if (substrings[i] != "")
{
if (i > 0)
{
sb.Append(", ");
}
sb.Append("\"");
sb.Append(substrings[i]);
sb.Append("\"");
needComma = true;
}
if (i < substrings.Length - 1)
{
if (needComma)
{
sb.Append(", ");
}
sb.Append("'\"'");
}

}
sb.Append(")");
return sb.ToString();
}

And yes, I tested it with all the edge cases. That's why the logic is so stupidly complex:

    foreach (string s in new[]
{
"foo", // no quotes
"\"foo", // double quotes only
"'foo", // single quotes only
"'foo\"bar", // both; double quotes in mid-string
"'foo\"bar\"baz", // multiple double quotes in mid-string
"'foo\"", // string ends with double quotes
"'foo\"\"", // string ends with run of double quotes
"\"'foo", // string begins with double quotes
"\"\"'foo", // string begins with run of double quotes
"'foo\"\"bar" // run of double quotes in mid-string
})
{
Console.Write(s);
Console.Write(" = ");
Console.WriteLine(XPathLiteral(s));
XmlElement elm = d.CreateElement("test");
d.DocumentElement.AppendChild(elm);
elm.SetAttribute("value", s);

string xpath = "/root/test[@value = " + XPathLiteral(s) + "]";
if (d.SelectSingleNode(xpath) == elm)
{
Console.WriteLine("OK");
}
else
{
Console.WriteLine("Should have found a match for {0}, and didn't.", s);
}
}
Console.ReadKey();
}

How to deal with single quote in xpath

try as below :-

self.b.find_element_by_xpath(".//*[contains(text(), \"Hanes Men's Graphic\")]")

or

self.b.find_element_by_xpath('.//*[contains(text(), "%s")]' % item_text)

or

self.b.find_element_by_xpath(".//*[contains(text(), \"%s\")]" % item_text)

Hope it will work..:)

How to search string with apostrophe quote with XPATH in XML?

You could switch ' with " and escape the apostrophe in Basic's:

$books = $xml->xpath('//book[contains(title,"Basic\'s")]');

Codepad Example

Escape Apostrophe in Selenium

Use a back-slash like \ before the sign you want to escape.

If you sometimes don't want so escape to much you can also use part of the attributes like:

//a[contains(@title, 's Schedule')]

Or with escape:

//a[@title='My Day\'s Schedule']

As an alternative you can also use other attributes like href instead of title.

Tip: use contains only when give part of the string, else use @attribute='string'



Related Topics



Leave a reply



Submit