XPath для элемента, значение атрибута которого заканчивается конкретной строкой?

Учитывая, что HTML содержит:

  <div tagname="779853cd-355b-4242-8399-dc15f95b3276_Destination" class="panel panel-default"></div>

Как написать следующее выражение в XPath:

Найти <div> элемент которого tagname атрибут заканчивается строкой 'Destination'

Я искал несколько дней, и я не могу придумать что-то, что работает. Среди многих я пробовал например:

div[contains(@tagname, 'Destination')]

7 ответов

XPath 2.0

//div[ends-with(@tagname, 'Destination')]

XPath 1.0

//div[substring(@tagname,string-length(@tagname) -string-length('Destination') +1) 
      = 'Destination']

XPath 2 или 3: всегда есть регулярное выражение

.//div[matches(@tagname,".*_Destination$")]

Ты можешь использовать ends-with (Xpath 2.0)

//div[ends-with(@tagname, 'Destination')]

Вы можете использовать ниже xpath, который будет работать с Xpath 1.0

//div[string-length(substring-before(@tagname, 'Destination')) >= 0 and string-length(substring-after(@tagname, 'Destination')) = 0 and contains(@tagname, 'Destination')]

В основном он проверяет, есть ли какая-либо строка (или нет строк) перед первым появлением Destination но не должно быть текста после Destination

Тестовый ввод:

<root>
<!--Ends with Destination-->
<div tagname="779853cd-355b-4242-8399-dc15f95b3276_Destination" class="panel panel-default"></div>
<!--just Destination-->
<div tagname="Destination" class="panel panel-default"></div>
<!--Contains Destination-->
<div tagname="779853cd-355b-4242-8399-dc15f95b3276_Destination_some_text" class="panel panel-default"></div>
<!--Doesn't contain destination-->
<div tagname="779853cd-355b-4242-8399-dc15f95b3276" class="panel panel-default"></div>
</root>

Тестовый вывод:

<div class="panel panel-default"
     tagname="779853cd-355b-4242-8399-dc15f95b3276_Destination"/>
<div class="panel panel-default" tagname="Destination"/>

Если вы зашли в это обсуждение решения на основе селена или селена-webdriver , Selenium по-прежнему поддерживает только xpath-1.0, где ends-with()не поддерживается.


Решение

Учитывая HTML:

      <div tagname="779853cd-355b-4242-8399-dc15f95b3276_Destination" class="panel panel-default"></div>

При использовании Selenium потенциальным решением было бы использованиеcontains()метод следующим образом:

      //div[contains(@tagname, 'Destination')]

размещение classатрибуты:

      //div[contains(@tagname, 'Destination') and @class='panel panel-default']

//div[заканчивается на (@tagname, 'Destination')] может не отображаться в DOM как совпадение, но будет работать при запуске кода.

Другое решение, совместимое с XPath 1.0:

      //div[contains(concat(@tagname, 'UNIQUE'), concat('Destination', 'UNIQUE'))]

Я использовал это при поиске записей в базе данных KeePass с помощью функции поиска выражения XPath:

      //Entry/String[contains(concat(Key, 'UNIQUE'), '/UNIQUE')]

найдены все записи, в которых есть пользовательское строковое поле, оканчивающееся на '/'.

Другие вопросы по тегам