15

I came up in a situation where I have to identify an element using XPath and my element starts with apostrophe ('). I will give the example below.

This is the usual way we write some XPath.

 By identifier = By.xpath("//span[@trans='WbOrderHeader.OneCancelsAnother']");

In the above code after that equals we write the WbOrderHeader.OneCancelsAnother inside the apostrophe. but what if my identifier starts with an apostrophe?

for example, the same code will be like this

By identifier = By.xpath("//span[@trans=''WbOrderHeader.OneCancelsAnother']");

so the identifier will be WbOrderHeader.OneCancelsAnother

There is one apostrophe (') at the beginning and there is none at the end. In this case, when I write the XPath the way I wrote here, it's not identifying. How can I solve this problem?

How to write XPath in this kind of situation?

1
  • Generally when programming we call ' the single quote.
    – sphennings
    Commented Mar 23, 2017 at 15:06

9 Answers 9

10

The character ' is an apostrophe. The colon character is :.

Selenium unfortunately only supports XPath 1.0, so this is tricky. You can do it by escaping the ' with a backslash like this:

By.xpath("//span[@trans=\"'WbOrderHeader.OneCancelsAnother\"]")
3
  • sorry about the confusion, i edited the question to apostrophe.
    – sarath
    Commented Mar 23, 2017 at 15:01
  • 3
    A slight correction - it is the browsers that support and limit XPath 1.0, not selenium (it does nothing with it, the evaluation is done by the browser) Commented Mar 25, 2017 at 5:12
  • Where is a ' being escaped in this example? Commented Aug 18 at 20:17
4

To make an apostrophe that's in XPath be interpreted literally, you can use the concat function that's defined in the W3C XPath recommendation.

Notes about this function:
1. Its format is as follows (where n ≥ 2 and each of the arguments is a string):
concat(s1, ..., sn)
2. It returns the concatenation of its parameters.
3. To add a sequence of one or more apostrophes to the string that's returned, enclose such a sequence in double quotes (when using Java, enclose in \") and use the result as one of the function arguments (as shown in the code below).

For your example, the following would work:

By.xpath("//span[@trans=concat(\"'\", 'WbOrderHeader.OneCancelsAnother')]");
3

Another option is to split the string into parts and use concat to put it back together again. Messy but it works and can be used over and over rather than dealing with it each time.

So this will return an xpath representation of the input string, or itself if there are no apostrophes:

public static String replaceApostrophes(String input)
{
    input = input.replaceAll("#comma#", ",");

    if (input.contains("'"))
    {
        String prefix = "";
        String[] elements = input.split("'");

        String output = "concat(";

        for (String s : elements)
        {
            output += prefix + "'" + s + "'";
            prefix = ",\"'\",";
        }

        if (output.endsWith(",")) 
            output = output.substring(0, output.length() - 2);

        output += ")";

        return output;
    }
    else 
        return "'" + input + "'";        
}
0
1

Using the contains expression should do the job. Something like:

By Identifier = By.XPath("//span[contains(@trans,'WbOrderHeader.OneCancelsAnother')]")

the contains can take an attribute you specify (@attribute) separated by a comma and then you can specify a value of that attribute. It can be part or full value to do the match against. This way you don't need to escape the apostrophe.

1

For all that saw this thread and went away disappointed, here's the answer:

Rather than '"+ varWithApostrophe +"' Do this: \""+ varWithApostrophe +"\"

Example: //span[contains(.,\""+ varWithApostrophe +"\")]

1
  • 1
    This would become a much stronger answer if you explained why
    – Ray Oei
    Commented Mar 11, 2019 at 21:18
1

Based on K-8's answer, here is a C# function:

public static string ReplaceApostrophes(string input)
{
    if (input.Contains("'"))
    {
        string prefix = "";
        var elements = input.Split('\'');

        string output = "concat(";

        foreach (var s in elements)
        {
            output += $"{prefix}'{s}'";
            prefix = ",\"'\",";
        }

        if (output.EndsWith(","))
        {
            output = output.Substring(0, output.Length - 2);
        }

        output += ")";

        return output;
    }
    else
    {
        return $"'{input}'";
    }
}
1

You can handle this by using double quote(")

//span[@trans="'WbOrderHeader.OneCancelsAnother"]

I have the below text with value Don't see your product?

I am handling with the following Xpath:

//*[contains(text(),"Don't see your product?")]

Let's know if that works.

1

You can use 'contains' in your XPath for this case. Your solution will be following:

By identifier = By.xpath("//span[contains(@trans, 'WbOrderHeader.OneCancelsAnother')]  

You can escape the need to handle the starting apostrophe altogether.

0

I encountered a similar situation where I need to write an xPath for an element shown below:

Element:

<img src="webwb/pzspacer.gif!!.gif" class="inactvIcon" data-ctl="["DatePicker"]" style="cursor:pointer;">

I was able to grep the element using below xPath, where I used the backslash to escape the characters [ and ".

Xpath:

//img[@data-ctl='\[\"DatePicker\"\]']

Hope this helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.