Поиск по всем вхождениям строки, только если узлы являются дочерними по отношению к определенному узлу, содержащему атрибут - PullRequest
0 голосов
/ 20 марта 2019

Рассмотрим этот пример:

<foo attr1="dummy">
   <bar1>
     some text #{abc} some text
   </bar1>
   <bar2>
     <bar2bar2>
        some text #{def} some text
     </bar2bar2>
   </bar2>
</foo>

Мне нужен запрос XPath 1.0 (который не поддерживает регулярное выражение), который ищет все вхождения # {*} , когда узлы(прямые или косвенные) дочерние элементы узла foo с атрибутом attr1 .Другими словами, запрос должен вернуть:

some text #{abc} some other text
some text #{def} some other text

Ответы [ 2 ]

1 голос
/ 20 марта 2019

Мне нужен запрос XPath 1.0 (который не поддерживает регулярные выражения), который ищет все вхождения # {*} , когда узлы являются (прямыми или косвенными) дочерними элементами узла foo с атрибутом attr1 .Другими словами, запрос должен вернуть

//foo//text()[contains(.,'#{')][contains(substring-after(.,'#{'),'}')]

Обратите внимание , что это выражение будет выбирать текстовые узлы.Если у вас смешанный контент (элементы с текстом и разметкой, такие как HTML p с em или span), то строка будет разбита на несколько текстовых узлов.Для этого вам понадобится что-то вроде этого ответа: Как мне найти узел в HTML с размеченным текстом путем поиска открытого текста?

1 голос
/ 20 марта 2019

(отвечая на оригинальный вопрос): попробуйте следующее выражение XPath-1.0:

//text()[starts-with(normalize-space(.),'#{') and substring(normalize-space(.),string-length(normalize-space(.)),1)='}' and  ancestor::foo[@attr1]]

Возвращает нужные text() узлы, но с начальными и конечными пробелами. Этого нельзя избежать в XPath-1.0, потому что функция normalize-space() принимает только один аргумент. В XPath-2.0 вы можете просто добавить /normalize-space() в конец выражения, чтобы обработать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...