Як вибрати вузол за допомогою XPath, якщо вузол брата або сестри має певне значення?


88

У мене є такий документ:

<a>
  <bb>abc</bb>
  <cc>ccc</cc>
  <dd>ddd</dd>
</a>
<a>
  <bb>zz</bb>
  <cc>1</cc>
  <dd>2</dd>
</a>

Як я можу отримати значення <cc>використання XPath, якщо воно <bb>є zz?


1
проблема полягає в тому, що я знаю, як отримати доступ до певного вузла, але я не маю уявлення про доступ до вузла, якщо брат чи сестра мають певне значення. Чи може це бути щось на зразок цього / a / cc / contains (/ a / bb = 'zz')?
HOE SENGKIANG

Відповіді:


100

Не впевнені, чому всі запитують братів і сестер, ви також можете перевірити наявність <bb/>-elements, що відповідають предикату з предиката <a/>'

//a[bb/text() = "zz"]/cc/text()

24
"Не знаю, чому всі запитують братів і сестер" : Можливо, тому, що питання
стосувалося

4
Здається, я насправді не читав заголовок. :) Відповідь у будь-якому випадку залишається чинною.
Йенс Ерат,

2
Ваші запити на відповіді для братів і сестер теж. Ви просто не використовували *-siblingвісь. +1, однак.
LarsH

Це не відповідає на запитання, але відповідає на моє фактичне запитання, яке я сформулював погано. Дякую!
Користувач9213


23

З: Як вибрати вузол за допомогою XPath, якщо вузол брата або сестри має певне значення?
Оскільки для наступних братів та сестер є лише "XPath Axes", ви можете використовувати одну з них, якщо позиція фіксована.

Але краще: шукайте, чи ccє у батька дитина bbз вартістю 'zz':

//cc[../bb='zz']

6
Або те, або //a[bb = 'zz']/cc.
Томалак

Не впевнені, що ви маєте на увазі під "лише осями XPath" для наступних братів та попередніх братів і сестер. Ви маєте на увазі той факт, що немає єдиної осі для всіх братів і сестер?
LarsH

@LarsH: Так, вибачте, (вибачте за мою погану англійську :-() - це те, що я намагався сказати. (Оскільки питання було для братів і сестер.)
hr_117

6

По-перше, ваш приклад - це неправильно сформований XML. Зважаючи на те, і що ви не дуже добре описали свої наміри (Що саме ви хочете вибрати, за якої умови?), Я припускаю, що ви хочете зробити це:

//cc[preceding-sibling::bb[text()="zz"]]/text()

Це відбирає

TEXT VALUES OF ALL <CC> ELEMENTS
//cc                                    /text()
    THAT HAVE A PRECEDING SIBLING <BB>
    [preceding-sibling::bb             ]
                          THAT HAS TEXT VALUE EQUAL TO "zz"
                          [text()="zz"]

Ви могли б написати також як

//bb[text()="zz"]/following-sibling::cc/text()

Будь ласка, подивіться на специфікацію , у ній є кілька добре читабельних прикладів, з яких ви дізнаєтесь багато нового.


1
@LarsH Дякуємо за виправлення з "не дійсний" на "не добре сформований". Сьогодні я дізнався щось нове.
Петр Янечек

4
//a/cc[../bb='zz']/text()

// a: Вибирає всі елементи 'a' незалежно від того, де вони знаходяться.

// a / cc: Вибирає елементи "cc", які є дочірніми елементами "a" (незалежно від того, де a).

..: Вибирає батьківський елемент поточного вузла.

[../bb='zz ']: де значення елемента "bb" брата або сестри дорівнює zz.

Довідково: http://www.w3schools.com/xsl/xpath_syntax.asp


4

Іншим рішенням цієї проблеми є

//bb[contains(.,'zz')]/../cc/text()

Пояснення : Будь-який, bbщо містить 'zz'рядок у всіх дочірніх вузлах, bbа потім переходить до батьківського вузла цього bbвикористання .., тепер ми можемо отримати доступ до ccтексту, що повертається.

Я сподіваюся, що пояснення не є складним.

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