XPath – как исключить текст из дочернего узла

Мне нужен этот вывод (пример):

я хочу это

Я работаю с документом XML/TEI, и мне нужно работать с выражением XPath, и я хочу выводить текст в div/u, но без текста внутри элемента узла, такого как "desc" или "vocal><desc" или текст между «anchor/><anchor/» (пример).

Из кода (пример):

<div>
<u> 
I want this but 
     *<anchor/><desc>I don't want this</desc><anchor/>
      <anchor/>I don't want this also<anchor/>
     <del type = "">I don't want this too</del>*
I want this
</u>
</div>

Я пытался использовать (пример):

TEI//u[not(desc)]

Но это исключает каждый <u> с <desc> внутри.

Ваше описание довольно запутанное, особенно. часть о «тексте между «anchor/><anchor/»». Любой текстовый узел между двумя элементами anchor в вашем примере будет дочерним элементом u и также будет выбран //u/text().

michael.hor257k 28.03.2024 17:03
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
78
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Это выражение XPath вернет текст всех тегов «u», исключая текст любых тегов «desc» или «anchor» внутри них:

TEI//u//text()[not(ancestor::desc) and not(ancestor::anchor)]

Это сработало, большое спасибо! Я буду применять этот метод и в других подобных ситуациях.

Rosmerade 28.03.2024 12:01

У этого есть немало проблем: (1) Он выбирает текст внутри del, чего ОП не хочет. (2) Требуется обновление для каждого нежелательного родителя или предка. (3) И desc, и anchor являются предками текстовых узлов, поэтому, по крайней мере, для примера, not(ancestor::desc) является избыточным. Вместо этого рассмотрим более простой подход.

kjhughes 28.03.2024 15:09

Старый ответ

Этот XPath,

//u/text()

выберет все дочерние текстовые узлы всех элементов u в документе:

I want this but 
I want this

Если вам нужны только первые дочерние текстовые узлы, используйте

//u/text()[1]

Обратите внимание, что при этом будут выбраны первые текстовые узлы всех элементов u в документе. Если вам нужен только первый из этих текстовых узлов, используйте

(//u/text())[1]

Обновленный ответ

Упс, комментарий @y.arazim заставил меня понять, что теги здесь:

<anchor/>I don't want this also<anchor/>

несмотря на свое расположение, являются самозакрывающимися, а не открывающими и закрывающими тегами вокруг текста. Я написал старый ответ на основе этой ошибки.

См. ответ @y.arazim (+1) для XPath, который соответствует его интерпретации требований OP (и правильно учитывает самозакрывающиеся теги anchor).

Если OP просто хочет, чтобы дочерние текстовые узлы u находились до или после любых одноуровневых элементов anchor, тогда этого XPath было бы достаточно:

//u/text()[not(preceding-sibling::anchor and following-sibling::anchor)]

Я подозреваю, что это правильный ответ (+1), но смотрите мой комментарий к вопросу.

michael.hor257k 28.03.2024 17:04

Результат, который я получаю при тестировании этого кода //u/text() на заданных входных данных, включает в себя «Я тоже этого не хочу».

y.arazim 29.03.2024 14:41

@y.arazim: Ты прав. из-за их расположения и моей невнимательности я неправильно прочитал текст в <anchor/>I don't want this also<anchor/> как окруженный открывающимися и закрывающимися anchor тегами, а не самозакрывающимися тегами. Я добавил обновление (и проголосовал за ваш ответ), чтобы ответить на ваш полезный комментарий. Спасибо.

kjhughes 29.03.2024 16:00

Спасибо всем за помощь. Этот "//u/text()[not(preceding-sibling::anchor и next-sibling::anchor)]" также был полезен для приема текста внутри узлов "привязки" (я удалил "not" из этого выражения) . И извините за мой плохой английский!

Rosmerade 03.04.2024 12:09

Я сделал это. В конце концов, правильным ответом будет следующее выражение: //u/text()[not(preceding-sibling::*[1][self::anchor] и next-sibling::*[1][self: :якорь])]

Rosmerade 03.04.2024 16:07
Ответ принят как подходящий

Если я прочитаю ваши требования как:

выберите любой текстовый узел, который является дочерним для u (т. е. не внутри другого элемента, такого как desc или del), но исключите текстовые узлы, находящиеся между двумя элементами anchor.

то я прихожу к следующему выражению:

//u/text()[not(preceding-sibling::*[1][self::anchor] and following-sibling::*[1][self::anchor])]

Применение его к данному входу дает:

" 
I want this but 
     **
I want this
"

который отличается от желаемого результата, но, тем не менее, соответствует заявленным требованиям.

Другие вопросы по теме