0

假设在一个 html 页面中有这三个锚点。使用 htmlunit 我想获取这些锚点内的数字(作为数字而不是文本)。

<a class="someclass" href="http://someaddress1.com">3.14</a>
<a class="someclass" href="http://someaddress2.com">1.22</a>
<a class="someclass" href="http://someaddress3.com">6.66</a>

该工作必须通过以下 testXPath 方法完成:

public static void testXPath () {

  WebClient webClient = new WebClient();
  webClient.setJavaScriptEnabled(false);
  webClient.setCssEnabled(false);

  try {

        final HtmlPage page = (HtmlPage) webClient.getPage("pageurl");

        String XPath="//a[@class='someclass']/number()";

        List<Object> list = (List<Object>) page.getByXPath(XPath);

        for (Objects : list) {
             System.out.println(s);
        }

  } catch (Exception e) {   
     e.printStackTrace();
  }
}

当我运行它时,我得到:

java.lang.RuntimeException: Could not retrieve XPath 
Caused by: javax.xml.transform.TransformerException: Unknown nodetype: number

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

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

但当,

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

我只得到第一个 href 值http://someaddress1.com


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

List<DomText> list = (List<DomText>) page.getByXPath("//a[@class='someclass']/text()");
for (DomText d : list) {
  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());
}

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

4

2 回答 2

1

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

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

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

于 2013-09-08T20:07:42.180 回答
0

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

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

于 2013-09-08T14:08:15.310 回答