使用XPath,如何选择包含特定字符串的任何节点 [英] Using XPATH, how to select ANY node that contains a certain string

查看:23
本文介绍了使用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")]成功并从第一个<description>元素中检索<en><fr>节点

如果不可能,没关系,我会列出我的XPath中的所有元素,但我仍然希望清楚地了解*选择器在contains()操作上下文中的行为。

推荐答案

术语节点(请参见XPath difference between child::* and child::node())和术语包含(请参见How to use XPath contains() for specific text?)不太精确,但下列XPath之一可能会满足您的需要:

  1. 所有节点string value包含子字符串"John"

    //node()[contains(.,"John")]
    
  2. 所有此类元素

    //*[contains(.,"John")]
    
  3. 所有此类属性

    //@*[contains(.,"John")]
    
  4. 所有此类文本节点

    //text()[contains(.,"John")]
    
  5. 所有元素其文本节点子项包含子字符串"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?

这篇关于使用XPath,如何选择包含特定字符串的任何节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆