我正在使用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
将其拆分为Text
s而不是一个{{1}的数组}}。这可能是问题吗?
答案 0 :(得分:2)
简短回答 - 使用.
代替text()
,即contains(., 'expression1')
更长的答案 - text()
是一个路径步骤,用于选择作为上下文节点的直接子节点的所有文本节点的集。 contains
函数期望它的参数是字符串,而不是节点集,并且在XPath 1.0中将节点集转换为字符串的规则是获取第一个节点的字符串值按文档顺序设置并完全忽略其他节点。因此,测试contains(text(), 'expression1')
仅查找第一个文本节点子节点。
如果您执行contains(., 'expression1')
,则第一个参数是包含单个节点(脚本元素)的集合,元素节点的字符串值是 all 的串联文档顺序中的后代文本节点。因此,这将查看脚本标记下的所有文本,而不仅仅是第一个文本节点子项。
通常,您很少需要在XPath中使用text()
。只有在绝对必须单独处理每个单独的文本节点时才需要它。在谓词中,我发现测试元素节点的字符串值几乎总能更好地捕获意图。