【问题标题】:org.jdom2.xpath doesn't return results on queries from html head elementorg.jdom2.xpath 不返回来自 html 头元素的查询结果
【发布时间】:2014-10-01 14:54:29
【问题描述】:

我正在使用org.jdom2.xpath 评估XPath 对html 文档的查询。 尝试从 head 元素中检索脚本文本,我尝试了以下查询:

/html/head/script[contains(text(), 'expression1') and contains(text(), 'expression2')]/text()

此查询在XPath Helper 和Chrome console ($x queries) 中返回一个结果,但使用org.jdom2.xpath 返回一个空结果集。

尝试更简单(但更重)的查询:

//script[contains(text(), 'expression1') and contains(text(), 'expression2')]/text()

产生相同的结果。

代码示例:

String xpath = "/html/head/script[contains(text(), 'expression1') and contains(text(), 'expression2')]/text()";
List<Text> tokeScriptResults = (List<Text>) xpathFactory.compile(xpath).evaluate(document);

事后思考:查看Document 对象,我发现由于脚本文本很长,jdom2 将其拆分为Texts 的数组,而不是一个长的Text。会不会是这个问题?

【问题讨论】:

    标签: java xpath jdom-2


    【解决方案1】:

    简答 - 使用 . 而不是 text(),即 contains(., 'expression1')

    更长的答案 - text() 是一个路径步骤,它选择作为上下文节点的直接子节点的所有文本节点的 set。 contains 函数期望它的参数是字符串,而不是节点集,并且在 XPath 1.0 中将节点集转换为字符串的规则是获取集合中 first 节点的字符串值按文档顺序并完全忽略其他节点。因此测试contains(text(), 'expression1') 只查看第一个文本节点子节点。

    如果您改为使用contains(., 'expression1'),则第一个参数是包含单个节点(脚本元素)的集合,元素节点的字符串值是 all 其后代文本的串联文档顺序中的节点。所以这将查看 script 标签下的所有文本,而不仅仅是第一个文本节点子节点。

    一般来说,您应该很少需要在 XPath 中使用text()。仅当您绝对必须单独处理每个单独的文本节点时才需要它。在谓词中,我发现测试元素节点的字符串值几乎总是能更好地捕捉意图。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-06
      • 1970-01-01
      • 2018-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-21
      • 1970-01-01
      相关资源
      最近更新 更多