2009-05-18 89 views
0

我正在使用WATIJ进行一些屏幕抓取,但无法读取HTML表(抛出NullPointerExceptions或UnknownObjectExceptions)。为了解决这个问题,我阅读了HTML并通过JTidy运行它以获得格式良好的XML。XPath无法通过ID找到表

我想使用XPath解析它,但即使表格在XML平原中的日期为空,也找不到<table ...>的。这里是我的代码:

XPathFactory factory=XPathFactory.newInstance(); 
XPath xPath=factory.newXPath(); 
InputSource inputSource = new InputSource(new StringReader(tidyHtml)); 
XPathExpression xPathExpression=xPath.compile("//table[@id='searchResult']"); 
String expression = "//table[@id='searchResult']"; 
String table = xPath.evaluate(expression, inputSource); 
System.out.println("table = " + table); 

该表是一个空字符串。

但是,表格在XML中。如果我打印tidyHtml字符串它显示

<table 
    class="ApptableDisplayTag" 
    id="searchResult" 
    style="WIDTH: 99%"> 

我之前,所以也许我失去了一些东西没有用的XPath。

任何人都可以设置我吗?谢谢。

回答

0

解决方案是放弃WATIJ并切换到Google WebDriver。 WebDriver记录了不同的浏览器如何在xpath语句中处理大小写。

0

我从来没有直接使用Java的XPath API,我总是通过dom4j或其他语言(Perl和C)使用它。但我对它如何正常工作有了很好的理解。起初,您应该将输入解析为DOM文档,这将非常有帮助。同样,如果你知道你的文档有ID,你应该通过加载用这种方式描述它的DTD或Schema来解析它,XML解析器将标记和标识具有正确ID的节点。完成此操作后,您可以使用DOM树中的代码。

的文档[XPath.evaluate(表达,项目)](http://java.sun.com/j2se/1.5.0/docs/api/javax/xml/xpath/XPath.html#evaluate(java.lang.String,%20java.lang.Object)表明,第二个元素应该是一个节点或的NodeList。这也许就是为什么你有充足的UnknownObjectExceptions的。

如果您的XML分析器是能够识别ID的元素,那么您可以访问具有与下面的XPath表达式中的ID的元素:

XPathExpression xPathExpression=xPath.compile("id('searchResult')"); 
xPathExpression.evaluate(document); // document is a DOM document instance 

使用XPath函数id()是用于访问元素的最有效的方式,即当元件使用一个ID并在DTD或Sc中以这种方式声明HEMA。

0

你xPath是正确的......不管它是失败的,它不是这样。

0

看起来问题主要在于JTidy。我可以通过执行以下操作来获取xpath来解析JTidy-ied结果:

删除全部“< & amp”>“ JTidy将xhtml返回为“< & amp> nbsp;”在标签之外。 删除 在标签中删除xmlns = ...属性 删除“head”标签。 (我使用了一些有趣的格式,因为HTML实体在正确输入时不会显示)

如果...元素,JTidy也会在文本内容的中间放置换行符。我将不得不看看其他的HTML - > XML转换选项。我给了眼镜蛇一个快速的尝试,但它也没能通过Id找到我的桌子。我还没有尝试手动清理Cobra的结果,所以我不知道它与JTidy相比如何。

如果您知道返回良好XML的HTML解析器,请让我知道。

1

我对JTidy一无所知,但是对于WATIJ,我相信你得到NullPointer和UnknownObject异常的原因是因为你的XPATH使用的是较低层的节点。因此,假设您使用“// table [@ id ='searchResult']”作为xpath来查找WATIJ中的表。那实际上不会工作,因为“table”是小写字母。对于WATIJ,您需要以大写形式包含所有节点名称,例如:“// TABLE [@ id ='searchResult']”。举个例子,假设您想要打印使用WATIJ在该表的行数,你会做到以下几点:

 
import watij.runtime.ie.IE; 
import static watij.finders.SymbolFactory.*; 

public class Example { 
    public static void main(String[] args) { 
     IE ie = new IE(); 
     ie.start("your_url_goes_here"); 
     System.out.println(ie.table(xpath, "//TABLE[@id='searchResult']").rowCount()); 
     ie.close(); 
    } 
} 

此代码或答案可能是不对的,因为我只用今天WATIJ开始。虽然我遇到了与xpaths完全相同的问题。花了我几个小时的搜索/测试之后,我才注意到这个页面上所有的xpath是如何被包含在内的:WATIJ User Guide一旦我改变了我的xpath中的外壳,WATIJ就能够找到这些对象,所以这也适用于你。

+0

良好的观察来访问。 Google WebDriver文档提到xpath语句的区分大小取决于您使用的浏览器。 – 2009-08-31 20:51:46

0

双引号绝对不是必需的,都不是大写。名称空间和/或DTD更可能是答案。

0

Uniue ID属性需要由ID()方法id('search')