Мне нужен этот вывод (пример):
я хочу это
Я работаю с документом 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> внутри.





Это выражение XPath вернет текст всех тегов «u», исключая текст любых тегов «desc» или «anchor» внутри них:
TEI//u//text()[not(ancestor::desc) and not(ancestor::anchor)]
Это сработало, большое спасибо! Я буду применять этот метод и в других подобных ситуациях.
У этого есть немало проблем: (1) Он выбирает текст внутри del, чего ОП не хочет. (2) Требуется обновление для каждого нежелательного родителя или предка. (3) И desc, и anchor являются предками текстовых узлов, поэтому, по крайней мере, для примера, not(ancestor::desc) является избыточным. Вместо этого рассмотрим более простой подход.
Этот 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), но смотрите мой комментарий к вопросу.
Результат, который я получаю при тестировании этого кода //u/text() на заданных входных данных, включает в себя «Я тоже этого не хочу».
@y.arazim: Ты прав. из-за их расположения и моей невнимательности я неправильно прочитал текст в <anchor/>I don't want this also<anchor/> как окруженный открывающимися и закрывающимися anchor тегами, а не самозакрывающимися тегами. Я добавил обновление (и проголосовал за ваш ответ), чтобы ответить на ваш полезный комментарий. Спасибо.
Спасибо всем за помощь. Этот "//u/text()[not(preceding-sibling::anchor и next-sibling::anchor)]" также был полезен для приема текста внутри узлов "привязки" (я удалил "not" из этого выражения) . И извините за мой плохой английский!
Я сделал это. В конце концов, правильным ответом будет следующее выражение: //u/text()[not(preceding-sibling::*[1][self::anchor] и next-sibling::*[1][self: :якорь])]
Если я прочитаю ваши требования как:
выберите любой текстовый узел, который является дочерним для 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
"
который отличается от желаемого результата, но, тем не менее, соответствует заявленным требованиям.
Ваше описание довольно запутанное, особенно. часть о «тексте между «anchor/><anchor/»». Любой текстовый узел между двумя элементами
anchorв вашем примере будет дочерним элементомuи также будет выбран//u/text().