XPath повертає лише елементи, що містять текст, а не його батьків


77

У цьому xml я хочу зіставити елемент, що містить 'match' (елемент random2)

<root>
 <random1>
  <random2>match</random2>
  <random3>nomatch</random3>
 </random1>
</root>

добре, поки що я маю:

//[re:test(.,'match','i')] (with re in the proper namespace)

це повертає random2, random1 і root ... Я хотів би отримати лише "random2"

будь-які ідеї?


Ви шукаєте відповідність, якщо воно містить слово де-небудь у тексті (наприклад, "подивіться, чи це збігатиметься зі словом"), або лише елементи, значення яких дорівнює "збіг" (ігноруючи навколишні пробіли)?
Мадс Хансен,

це не так актуально, або буде працювати. Проблема полягала головним чином у тому, що вона повертала і своїх батьків
Джуліан

Відповіді:


165

Ви хочете знайти елементи, що містять "збіг", або рівний "збіг"?

Тут буде знайдено елементи, які мають текстові вузли, що дорівнюють "збігу" (не відповідає жодному з елементів через пробіли, що ведуть та відстають random2):

//*[text()='match']

Це знайде всі елементи, які мають текстові вузли, що дорівнюють "збігу", після видалення пробілів, що ведуть і відстають (збігів random2):

//*[normalize-space(text())='match']

Буде знайдено всі елементи, що містять "match" у текстовому значенні вузла (match random2і random3):

//*[contains(text(),'match')]

Це рішення XPATH 2.0 використовує matches()функцію та шаблон регулярного виразу, який шукає текстові вузли, що містять "збіг" і починаються на початку рядка (тобто ^) або межі слова (тобто \W) і закінчуються кінцем рядка (тобто $) або межа слова. Третій параметр iобчислює регістр шаблону, що не враховує регістр. (матчі random2)

//*[matches(text(),'(^|\W)match($|\W)','i')]

Ваше друге твердження не відповідає дійсності. Підказка: візьміть елемент із декількома текстовими вузлами, перший текстовий вузол не містить "збігу".
Dimitre Novatchev

Дякую @Dimitre. Оновив його чимось, що повинно бути більш надійним.
Мадс Хансен,

насправді я хочу запустити конкретний запит із регулярним виразом, наприклад '^ ma (t | T). *' Я можу використати перший? //*[text()='^ma(t|T).* '] так?
Джуліан

Якщо ви хочете використовувати регулярний вираз, тоді ви використаєте щось на зразок останнього прикладу. Regex не підтримується в XSLT 1.0, тому для його використання вам знадобиться таблиця стилів XSLT 2.0 та процесор XSLT 2.0 (наприклад, саксонська).
Мадс Хансен,

Я вважаю, що це //*/text()[normalize-space(.)='match']/parent::*повинно бути //*[normalize-space(text())='match']чи//*[normalize-space(./text())='match']
neaumusic

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