Как я могу найти точное значение, используя xpath в Selen Webdriver для текста, который содержит? - PullRequest
1 голос
/ 26 марта 2019

У меня проблема с выбором точного текста 'Section' из кода с использованием xpath.

** Для ясности, я требую, чтобы точный выбор текста был сделан из innerText или innerHTML элемента, если это возможно, а не из id. **

Я могу использовать функцию содержимого текста, но это приводит к тому, что другие частичные совпадения, которые содержат 'Раздел', также возвращаются / выделяются:


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

Я пытался использовать следующие методы, но я не знаю, правильно ли я понял синтаксис, поскольку ничего не возвращается / не подсвечивается:


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

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

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

Это то, что отображается при проверке узла Section:


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

Это то, что показано в свойствах элемента:


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

Вот XML, который показывает другие частичные совпадения, которые возвращаются:

<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 ]

2 голосов
/ 26 марта 2019

Это было сложно.Проблема в том, что у вас есть несколько похожих опций, каждый из которых содержит «Раздел», и их трудно отличить друг от друга.К этому следует добавить, что каждый из них содержит неразрывный пробел &nbsp;, что означает, что normalize-space() также не будет работать (напрямую).

Но ... Я обнаружил, что приведенный ниже XPath будет работать.

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

normalize-space() удаляет пробелы (но не &nbsp), поэтому вы должны добавить его туда с помощью \u00a0.Я проверил это локально, и он работает.

0 голосов
/ 27 марта 2019

Вот метод, который будет извлекать текст только из родительского элемента. (исключить текст у ребенка (ren))

В 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()

Этот метод будет перебирать все firstChild (прямые потомки) и извлекать весь текст из всех текстовых узлов.

В этом контексте Если вы хотите получить текст li с идентификатором GOS--/40, используйте метод, описанный ниже.

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

Обмен этим методом, по крайней мере, может помочь другим (если не ОП в этом контексте).

Реализация C #: (не тестировалась)

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");

Использование:

string output = get_pure_text(driver,element)
0 голосов
/ 26 марта 2019

Позвольте мне бросить свою шляпу в кольцо ....

//li[(normalize-space(text()) = 'Section')]
0 голосов
/ 26 марта 2019

вы можете попробовать следующую XPath, чтобы найти узел раздела

Попробуй, если поможет

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

0 голосов
/ 26 марта 2019

Попробуйте выполнить xpath, посмотрите, поможет ли это.

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

OR

  //li[@class='nodecollapsed item parent-node xh-highlight'][@xpath='1']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...