Який правильний XPath для вибору атрибутів, що містять “foo”?


176

З огляду на цей XML, що XPath повертає всі елементи, propатрибут яких містить Foo(перші три вузли):

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

1
Чому всі дивляться на атрибут "опора"? Я щось пропустив? Це просто говорить отримати перші три вузли.

6
Усі дивляться на атрибут опори, тому що саме про це запитали. Отримайте всі вузли, де в опорі є "Foo". Додайте <a prop="Foo5" />, і ви побачите, чому це не просто "перші три вузли" ..
erlando

Питання в тілі недостатньо сформульоване, незалежно від назви. Чи справді foo може бути в будь-якому атрибуті опори, або ви серйозно просто хочете перших трьох вузлів?

3
Так, зверніться до назви будь ласка (і сміливо редагуйте).
ripper234

Якщо вам потрібно порівняння з
великим регістром, див. Find

Відповіді:


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

Це дозволить шукати всі елементи "a" у вашому XML-документі, незалежно від того, що вони вкладені в "blah" елемент

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

Я додав це заради ґрунтовності та в дусі stackoverflow. :)


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

Вісь - пошук кожного вузла під ним і самого вузла. Часто краще сказати це, ніж //. Я стикався з деякими реалізаціями, де // означає будь-де (decendant або self кореневого вузла). Інші використовують вісь за замовчуванням.

* or /bla/a

Тег - підстановочна відповідність, і / bla / a - абсолютний шлях.

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

Умова в межах []. @prop - це скорочення для attribute :: prop, оскільки атрибут - інша вісь пошуку. Можна також вибрати перші 3 за допомогою функції position ().


6

John C є найближчим, але XPath чутливий до регістру, тому правильним XPath було б:

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

4

Ви спробували щось на кшталт:

// a [містить (@prop, "Foo")]

Я ніколи раніше не використовував функцію містить, але підозрюю, що вона повинна працювати як рекламується ...


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

4

Якщо вам також потрібно відповідати вмісту самого посилання, використовуйте text ():

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



1

Для наведеного вище коду ... // * [містить (@ prop, 'foo')]


це для будь-якого елемента з foo in, але атрибут повинен бути "prop"
digiguru

1

спробуйте це:

// a [містить (@ prop, 'foo')]

які повинні працювати для будь-яких тегів "a" в документі

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.