使用XPath,如何选择包含特定字符串的任何节点 [英] Using XPATH, how to select ANY node that contains a certain string
问题描述
假设我有一个如下所示的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")]
成功并从第一个<description>
元素中检索<en>
和<fr>
节点
如果不可能,没关系,我会列出我的XPath中的所有元素,但我仍然希望清楚地了解*
选择器在contains()
操作上下文中的行为。
推荐答案
术语节点(请参见XPath difference between child::* and child::node())和术语包含(请参见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")]]
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?
这篇关于使用XPath,如何选择包含特定字符串的任何节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!