Какой правильный XPath для выбора атрибутов, содержащих «foo»?

176

Учитывая этот XML, какой XPath возвращает все элементы, propатрибут которых содержит Foo(первые три узла):

<bla>
 <a prop="Foo1"/>
 <a prop="Foo2"/>
 <a prop="3Foo"/>
 <a prop="Bar"/>
</bla>
ripper234
источник
1
Почему все смотрят на атрибут "проп"? Я что-то пропустил? Это просто говорит получить первые три узла.
6
Все смотрят на атрибут реквизита, потому что это то, что спросили. Получить все узлы, где проп содержит "Foo". Добавьте <a prop="Foo5" />, и вы поймете, почему это не просто «первые три узла» ..
erlando
Вопрос в теле сформулирован плохо, независимо от названия. Действительно ли foo может быть в каком-либо атрибуте проп, или вы просто хотите первые три узла?
3
Да, обратитесь к названию, пожалуйста (и не стесняйтесь редактировать).
ripper234
Если вам нужно сравнение без учета регистра, см. « Найти элемент без
Майкл

Ответы:

307
//a[contains(@prop,'Foo')]

Работает, если я использую этот XML, чтобы получить результаты обратно.

<bla>
 <a prop="Foo1">a</a>
 <a prop="Foo2">b</a>
 <a prop="3Foo">c</a>
 <a prop="Bar">a</a>
</bla>

Изменить: Еще одна вещь, которую следует отметить, что хотя XPath выше вернет правильный ответ для этого конкретного XML, если вы хотите гарантировать, что вы получите только элементы "a" в элементе "bla", вы должны, как и другие упоминали, также использовать

/bla/a[contains(@prop,'Foo')]

Это будет искать вас всех элементов "а" во всем документе XML, независимо от того, были ли вложены в элемент "бла"

//a[contains(@prop,'Foo')]  

Я добавил это ради тщательности и в духе stackoverflow. :)

evilhomer
источник
3
xmlme.comтеперь перенаправляет на другой хост и, по-видимому, не размещает инструмент или что-то подобное.
jpmc26
26

Этот XPath даст вам все узлы, которые имеют атрибуты, содержащие 'Foo', независимо от имени узла или имени атрибута:

//attribute::*[contains(., 'Foo')]/..

Конечно, если вас больше интересует содержимое самого атрибута, а не его родительский узел, просто удалите / ..

//attribute::*[contains(., 'Foo')]
Алекс Бейненсон
источник
2
Для всех узлов//@*[contains(., 'Foo')]
Алиопи
16
descendant-or-self::*[contains(@prop,'Foo')]

Или:

/bla/a[contains(@prop,'Foo')]

Или:

/bla/a[position() <= 3]

расчлененный:

descendant-or-self::

Ось - поиск через каждый узел внизу и сам узел. Часто лучше сказать это, чем //. Я сталкивался с некоторыми реализациями, где // означает где угодно (потомок или self корневого узла). Другой использует ось по умолчанию.

* or /bla/a

Тег - это подстановочный знак, а / bla / a - абсолютный путь.

[contains(@prop,'Foo')] or [position() <= 3]

Условие в пределах []. @prop - это сокращение для attribute :: prop, так как attribute это еще одна ось поиска. В качестве альтернативы вы можете выбрать первые 3 с помощью функции position ().

1729
источник
6

John C - самый близкий, но XPath чувствителен к регистру, поэтому правильный XPath будет:

/bla/a[contains(@prop, 'Foo')]
Метро Смурф
источник
4

Вы пробовали что-то вроде:

// a [содержит (@prop, "Foo")]

Я никогда раньше не использовал функцию contains, но подозреваю, что она должна работать как рекламируется ...

toddk
источник
@toddk ... вы указали несуществующий атрибут: @foo. Вы хотели бы нацелиться на @prop ;-)
Metro Smurf
4

Если вам также необходимо сопоставить содержимое самой ссылки, используйте text ():

//a[contains(@href,"/some_link")][text()="Click here"]

SomeDudeSomewhere
источник
2

/ bla / a [содержит (@prop, "foo")]

Дэвид Хилл
источник
1

Для кода выше ... // * [содержит (@ prop, 'foo')]

digiguru
источник
это для любого элемента с foo in, но атрибут должен быть «prop»
digiguru
1

попробуй это:

// а [содержит (@ пропеллер, 'Foo')]

это должно работать для любых тегов "а" в документе

Дани Дюран
источник