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.