Почему normalize-space (text ()) не работает с предшествующим дочерним элементом? - PullRequest
3 голосов
/ 15 апреля 2019

Нет сомнений в том, что это чрезвычайно просто, но для меня это просто не «щелкнет», несмотря на исследования, которые я провел до сих пор.Имеются следующие два примера HTML:

Пример 1

<div _ngcontent-c35="" class="row facet-container ng-star-inserted">
    <div _ngcontent-c35="" class="searchresult-header">
        Locatie
    </div>
</div>

Пример 2

<div _ngcontent-c42="" class="row facet-panel ng-star-inserted">
    <div _ngcontent-c42="" class="facet-panel-header brand-pointer" data-target="#ft5" data-toggle="collapse">
        <span _ngcontent-c42="" class="icon-plus ng-star-inserted" data-target="#ft5" data-toggle="collapse">
        </span> 
        Locatie
    </div>
    <div _ngcontent-c42="" class="collapse" id="ft5">
    </div>
</div>

Теперь у меня естьследующий фрагмент xpath:

// div [.// div [normalize-space (text ()) = 'Locatie']]

В соответствии с другими questions и веб-сайты о xpath, text () выбирают текстовые узлы, непосредственно нисходящие от узла, по которому мы ищем.Поэтому в примере № 1 я ожидаю получить первый дочерний элемент "div".Это происходит правильно: никаких проблем нет.

Я ожидаю того же результата в примере # 2.Однако это не так: очевидно, элемент «span» нарушает этот конкретный поиск.Когда я удаляю его вручную, я успешно получаю необходимый элемент "div".Почему поиск прерван?Текст по-прежнему должен быть прямым потомком элемента div, независимо от того, есть ли элемент span там или нет.

TLDR: Почему элемент "span" мешает мне найти второй "div"элемент в примере № 2?

Ответы [ 3 ]

2 голосов
/ 15 апреля 2019

Полагаю, это потому, что normalize-space(text())='Locatie'] намеревается проверить первый дочерний текстовый узел (который на самом деле является просто пустой строкой), а вам нужно проверить второй один:

//div[.//div[normalize-space(text()[2])='Locatie']]

Если вам нужен общий XPath, который будет работать в обоих случаях, попробуйте

//div[normalize-space(div)='Locatie']
2 голосов
/ 16 апреля 2019

Как Джейсон ответил это потому, что подпись функции normalize-space() из спецификации:

Функция : string normalize-space ( string ?)

В XPath 1.0, когда требуется строковый аргумент, язык применяетсяпреобразование типов с помощью функции string().Из спецификации:

Набор узлов преобразуется в строку, возвращая строковое значение узла в наборе узлов, который является первым в порядке документов.Если набор узлов пуст, возвращается пустая строка.

Таким образом, результирующий набор узлов из теста text() узлов уменьшается до первого узла в порядке документов и затем этот узел преобразуется в его строковое значение .

В этом отношении, когда всегда наблюдаются только пробельные символы, только текстовые узлы замечают: ваш элемент div имеет два текстаузлы:

<div>
    <div>
        <!-- HERE ENDS THE FIRST --><span>
        </span> 
        Locatie
    <!-- HERE ENDS THE SECOND --></div>
    <div>
    </div>
</div>

Всякий раз, когда у вас смешанная разметка содержимого, лучше использовать строковое значение, а не текстовые узлы. В противном случае вы должны использовать это выражение:

//div[.//div/text()[normalize-space()='Locatie']]
0 голосов
/ 15 апреля 2019

Это может иметь какое-то отношение к белому тексту / пробелам (это намного выше моей зарплаты ...), потому что с этим изменением фокуса следующее выражение, кажется, работает с большинством (не всеми) тестировщиками xpath:

.//div[text()[contains(.,'Locat')]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...