Java org.jdom2.xpath不';t从html头元素返回查询结果

Java org.jdom2.xpath不';t从html头元素返回查询结果,java,xpath,jdom-2,Java,Xpath,Jdom 2,我正在使用org.jdom2.xpath评估xpath对html文档的查询。 试图从head元素检索脚本文本,我尝试了以下查询: /html/head/script[contains(text(), 'expression1') and contains(text(), 'expression2')]/text() 此查询在和中都返回一个结果,但使用org.jdom2.xpath重新运行一个空结果集 尝试更简单(但更重)的查询: 产生相同的结果 代码示例: String xpath = "/h

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

/html/head/script[contains(text(), 'expression1') and contains(text(), 'expression2')]/text()
此查询在和中都返回一个结果,但使用
org.jdom2.xpath
重新运行一个空结果集

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

产生相同的结果

代码示例:

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

事后思考:查看
文档
对象,我发现由于脚本文本非常长,
jdom2
将其拆分为一个
文本
数组,而不是一个长
文本
。这可能是问题吗?

简短回答-使用
而不是
text()
,即
包含(,'expression1')

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

如果改为执行
contains(,'expression1')
,则第一个参数是包含单个节点(脚本元素)的集合,元素节点的字符串值是其所有子代文本节点按文档顺序的串联。因此,这将查看脚本标记下的所有文本,而不仅仅是第一个文本节点子节点

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

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