How can I find the exact value using xpath in selenium webdriver for text that contains  ?

3.3k Views Asked by At

I'm having an issue selecting the exact text 'Section' from the code using xpath.

** To be clear I require the exact text selection to be made from the innerText or innerHTML of the element if that is possible, not the id. **

I'm able to use the contains text function, but that results in other partial matches that contain 'Section' being returned/highlighted as well:


//div[@aria-hidden='false']//ul/li[contains(text(),'Section')]

I've tried using the following methods, but I don't know if I've got the syntax correct, as nothing is returned/highlighted:


//div[@aria-hidden='false']//ul/li[text()='Section')]

//div[@aria-hidden='false']//ul/li[.='Section']

//div[@aria-hidden='false']//ul/li[normalize-space(.)='Section']

This is what is shown when inspecting the Section node:


<li id="GOS--/40" class="nodecollapsed item parent-node xh-highlight" style="" xpath="1">
                                Section&nbsp;<span class="child-count"></span>
                            </li>

This is what is shown in the element properties:


id: "GOS--/40"
innerHTML: "↵                                Section&nbsp;<span class="child-count"></span>↵                            "
innerText: " Section "

Here is the xml which shows the other partial matches that are returned:

<div class="selection-list-dialog modal-dialog Dialog">
    <div class="modal-content">
        <div class="modal-header SectionHeader">
            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
            <span class="modal-title" data-lang="StandardItems">Standard Items</span>
        </div>
        <div class="modal-body selection-list-container" style="margin-top: 30px" id="base">
            <div>
                <span data-lang="SelectItemInstructions">Select the items you are interested in from the list.</span>
            </div>
            <br/>
            <div class="pull-left selection-tree-container">
                <h4 class="selection-list-title">
                    <span data-lang="Available">Available</span>                    
                </h4>
                <ul class="selection-list selection-tree-list">



                            <li id="CS--/14" class="nodecollapsed item parent-node">
                                Country Section&nbsp;<span class="child-count"></span>
                            </li>                        


                            <li id="Sec1--/23" class="nodecollapsed item parent-node">
                                Section 1&nbsp;<span class="child-count"></span>
                            </li>


                            <li id="Sec2--/24" class="nodecollapsed item parent-node">
                                Section 2&nbsp;<span class="child-count"></span>
                            </li>


                            <li id="GOS--/40" class="nodecollapsed item parent-node">
                                Section&nbsp;<span class="child-count"></span>
                            </li>


                            <li id="RS--/43" class="nodecollapsed item parent-node">
                                Regional Section&nbsp;<span class="child-count"></span>
                            </li>

5

There are 5 best solutions below

15
On BEST ANSWER

This was a tough one. The problem is that you have a number of similar options all containing "Section" in some flavor and it's hard to distinguish them apart. What adds to this is that each one contains a non-breaking space &nbsp; which means that normalize-space() won't work (directly) either.

But... I found that the below XPath will work.

//li[normalize-space()='Section\u00a0']

normalize-space() removes whitespace (but not &nbsp) so you have to add it in there with \u00a0. I've tested this locally and it's working.

11
On

Try following xpath see if it helps.

 //li[starts-with(@id,'GOS')][@class='nodecollapsed item parent-node xh-highlight']

OR

  //li[@class='nodecollapsed item parent-node xh-highlight'][@xpath='1']
1
On

you can try the below XPath to find a section node

Try if it helps

//li[@id='GOS--/40'][contains(text(),'Section')]

5
On

Let me throw my hat into the ring....

//li[(normalize-space(text()) = 'Section')]
2
On

Here is the method that will fetch the text from the parent only. (exclude the text in the child(ren))

In Python:

def get_pure_element_text(element):
    return driver.execute_script(
        """
        var parent = arguments[0];
        var child = parent.firstChild;
        var textValue = "";
        while(child) {
            if (child.nodeType === Node.TEXT_NODE)
                    textValue += child.textContent;
                    child = child.nextSibling;
        }
        return textValue;""",
        element).strip()

This method will iterate all the firstChild (direct children) and extract all text from all the text nodes.

In this context If you want to retrieve the text of li which have the id GOS--/40 then use the method as below.

element = driver.find_element_by_xpath("//li[@id='GOS--/40']")
print(get_pure_element_text(element))   

Sharing this method, at least might help the others (if not the OP in this context).

C# implementation:(not tested)

string get_pure_text(IWebDriver driver, IWebElement element){
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
    return (string)js.ExecuteScript(""""
        var parent = arguments[0];
        var child = parent.firstChild;
        var textValue = "";
        while(child) {
            if (child.nodeType === Node.TEXT_NODE)
                    textValue += child.textContent;
                    child = child.nextSibling;
        }
        return textValue;""",
        element");

Usage:

string output = get_pure_text(driver,element)