如何解决使用 XPATH,如何选择包含某个字符串的任何节点
假设我有一个这样的 XML 文件:
<books>
<book>
<title>John is alive</title>
<abstract>
A man is found alive after having disappeared for 10 years.
</abstract>
<description>
<en> John disappeared 10 years ago. Lorem ipsum dolor sit amet ...</en>
<fr> Il y a 10 ans,John disparaissait. Lorem ipsum dolor sit amet ...</fr>
</description>
<notes>First book in the series,where the character is introduced</notes>
</book>
<book>
<title>The disappearance of John</title>
<abstract>
A prequel to the book "John is alive".
</abstract>
<description>
<en> He lead an ordinary life,but then ... lorem ipsum dolor sit amet ...</en>
<fr> Sa vie était tout à fait ordinaire,mais ... lorem ipsum dolor sit amet ...</fr>
</description>
<notes>Second book in the "John" series,but first in chronological order</notes>
</book>
</books>
我的问题很简单:如何使用 XPATH 获取包含单词 John
的所有节点的集合?
显然,我可以指定一系列节点并且工作正常:
(//title | //abstract | //description/* | //notes)[contains(lower-case(text()),"john")]
但如果我的 XML 增长(并且会增长!),并且在结构的各个级别添加新元素,我不想经常返回并调整我的 XPATH。
我不明白的是为什么像这样的通用语句
//*[contains(lower-case(text()),"john")]
失败并显示此错误消息 Required cardinality of first argument of lower-case() is one or zero
。
然而,并非所有带星号的语句都会失败。
例如:
//books/book/*[contains(lower-case(text()),"john")]
失败并显示上述错误消息
同时
//books/book/*/*[contains(lower-case(text()),"john")]
成功并从第一个 <en>
元素中检索 <fr>
和 <description>
节点
如果不可能,那好吧,我将列出 XPATH 中的所有元素,但我仍然想清楚地了解 *
选择器在 contains()
上下文中的行为操作。
解决方法
对于术语 nodes(参见 XPath difference between child::* and child::node())和术语 contains(参见 How to use XPath contains() for specific text?)存在一些歧义,因为它不够精确,但以下 XPath 之一可能会满足您的需求:
-
string value 包含子字符串
"John"
的所有 节点://node()[contains(.,"John")]
-
所有这样的元素:
//*[contains(.,"John")]
-
所有这些属性:
//@*[contains(.,"John")]
-
所有这样的文本节点:
//text()[contains(.,"John")]
-
所有带有包含子字符串
"John"
的文本节点子节点的元素://*[text()[contains(.,"John")]]
请注意,#1 将包含 books
,但 #5 将排除它。见Testing text() nodes vs string values in XPath。
如果您使用的是 XPath 2.0,则可以将上述任何 XPath 中的 contains(.,"John")
替换为 contains(lower-case(.),"john")
。另见Case insensitive XPath contains() possible?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。