Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java HtmlUnit使用XPath函数number()和string()时出错_Java_Xpath_Htmlunit - Fatal编程技术网

Java HtmlUnit使用XPath函数number()和string()时出错

Java HtmlUnit使用XPath函数number()和string()时出错,java,xpath,htmlunit,Java,Xpath,Htmlunit,假设在html页面中有以下三个锚。 使用htmlunit,我希望获得这些锚定中的数字(作为数字而不是文本) 当我只想获取href值(作为字符串)时,也会发生相同的错误。在这种情况下: String XPath="//a[@class='someclass']/@href/string()"; 但是当 String XPath="string(//a[@class='someclass']/@href)"; 我只得到第一个href值http://someaddress1.com 我知道我可以

假设在html页面中有以下三个锚。 使用htmlunit,我希望获得这些锚定中的数字(作为数字而不是文本)

当我只想获取href值(作为字符串)时,也会发生相同的错误。在这种情况下:

String XPath="//a[@class='someclass']/@href/string()";
但是当

String XPath="string(//a[@class='someclass']/@href)";
我只得到第一个href值
http://someaddress1.com


我知道我可以将这些数字作为字符串,然后将它们解析为双精度

List<DomText> list = (List<DomText>) page.getByXPath("//a[@class='someclass']/text()");
for (DomText d : list) {
  System.out.println(Double.parseDouble(list.get(i).toString()));
}
List List=(List)page.getByXPath(“//a[@class='someclass']/text()”;
for(DOMDTEXT:列表){
System.out.println(Double.parseDouble(list.get(i.toString()));
}
我可以使用.getValue()来获取HREF

List<DomAttr> list = (List<DomAttr>) page.getByXPath("//a[@class='someclass']/@href");
for (DomAttr d : list) {
  System.out.println(list.get(i).getValue());
}
List List=(List)page.getByXPath(“//a[@class='someclass']/@href”);
用于(DomAttr d:列表){
System.out.println(list.get(i.getValue());
}

但事实并非如此。我想使用XPath函数来实现这一点(我猜它会更快)。

表达式
//a[@class='someclass']/number()
在XPath 2.0中是合法的,但在XPath 1.0中不合法,因此如果您想使用该语法,您需要确保Java应用程序插入XPath 2.0引擎,如Saxon 9。但我怀疑您正在使用的API(比如
getByXPath
)是否在设计时考虑到了XPath2.0,并允许您返回值序列。JAXP允许您插入Saxon而不是Xalan,但其API不允许您返回原语值序列


因此,经常需要更改的不仅仅是XPath引擎。

正如Martin所说,这是XPath 2.0的一个特性。HtmlUnit目前不支持XPath 2.0。这意味着您不能使用该表达式

我建议通过在XPath之外添加解析来解决这个问题。看起来没那么糟糕,实际上这是唯一的出路。当然,您可以将其提取到一些方法中来执行字段提取和解析,这样看起来会更好


关于为什么不支持XPath2.0的更多细节:实际上,是HtmlUnit不支持XPath2.0。只是XPath是在
org.apache.XPath.*
中处理的,它目前不支持2.0。如果添加了对较新XPath版本的支持,那么您将能够在
getByXPath
getFirstByXPath
方法中使用XPath 2.0表达式。

您可以使用
number()
函数(在XPath 1.0中可用),但由于它只为节点集中的第一个节点返回1个值,例如,在您的情况下,
number(//a[@class='someclass'])
返回
3.14
,您必须循环链接,例如
//a[@class='someclass']
,然后对每个链接调用
number(.)
。在您的应用程序代码中可能更容易操作谢谢您的回答!我不知道Saxon。如果它支持XPath 2,我会选择它。奇怪的是它不允许返回原始值序列。我想知道
//a[@class='someclass']/number()
返回一个双数值序列,Saxon自己的API当然允许您计算这些表达式并处理这些值。只有Saxon也支持的JAXP XPath API不适合处理XPath 2.0类型系统的丰富性。我对Saxon有一点经验,似乎只适合xml。因此,我花了大部分时间使用htmlunit和jtidy将html转换为xml。这似乎是一个非常困难的情况,我没有得到我想要的结果期待。有很多ψονΔιτιονσ可以使html页面符合Saxon要求的格式良好的xml。只是想知道我是否遗漏了一些关于Saxon的XPath 2.0实现的信息。它是否仅用于xml?由于是一种
xml路径语言,XPath的名称中有
X
,因此根据其定义和规范,它是一种XPath的实现是为了使用XML。另一方面,Saxon本身不是XML解析器,它使用Xerces之类的XML解析器,Java体系结构允许您插入TagSoup()之类的HTML解析器,或者替代XML解析器。我之所以这么问,是因为我没有遇到过关于使用XPath1.0和Xalan的html的复杂问题。谢谢你的帮助。有什么变化吗?
String XPath="string(//a[@class='someclass']/@href)";
List<DomText> list = (List<DomText>) page.getByXPath("//a[@class='someclass']/text()");
for (DomText d : list) {
  System.out.println(Double.parseDouble(list.get(i).toString()));
}
List<DomAttr> list = (List<DomAttr>) page.getByXPath("//a[@class='someclass']/@href");
for (DomAttr d : list) {
  System.out.println(list.get(i).getValue());
}