2010-09-01 40 views
1

我试图用dom4j解析一个xhtml文档。如果我只是打印出文件,我可以看到整个文件,所以我知道它正在正确加载。我试图选择的两个div在文档中完全相同。dom4j XPath不工作解析xhtml文档

html 
    body 
    div 
    table 
     tbody 
     tr 
     td 
     table 
      tbody 
      tr 
      td 
       div class="definition" 
       div class="example" 

我的代码是

List<Element> list = document.selectNodes("//html/body/div/table/tbody/tr/td/table/tbody/tr/td"); 

但该列表是空的,当我做System.out.println(list);

如果我只做List<Element> list = document.selectNodes("//html");它实际上与它一个元素返回一个列表。所以我很困惑我的xpath有什么问题以及为什么它找不到这些div

回答

3

尝试将xhtml命名空间声明为xpath,例如将其绑定到前缀x并使用//x:html/x:body...作为XPath表达式(另请参阅this article,但这适用于Groovy,不适用于普通Java)。大概就像下面应该这样做在Java中:

DefaultXPath xpath = new DefaultXPath("//x:html/x:body/..."); 
Map<String,String> namespaces = new TreeMap<String,String>(); 
namespaces.put("x","http://www.w3.org/1999/xhtml"); 
xpath.setNamespaceURIs(namespaces); 

list = xpath.selectNodes(document); 

(未经测试)

+0

这工作完美!我没有意识到你可以做到这一点。我还有一个额外的div,我需要在路径中。但是我没有使用x就再次尝试了它:它没有以这种方式工作,所以你的解决方案做到了。我认为解析xhtml有问题vs普通的xml。 – 2010-09-01 22:06:28

1

什么只是 “//格”?或者“// html/body/div/table/tbody”?我发现很长的文字XPath表达式很难调试,因为我的眼睛很容易被欺骗...所以我把它们分解,直到它工作,然后重新构建备份。

+0

那正是我想要做的。多数民众赞成我是如何抓住失踪的股利。但不幸的是,我仍然需要安德烈的答案,以使路径工作,即使我有正确的顺序元素 – 2010-09-01 22:15:28

+0

啊,是的...我错过了'xhtml'部分,所以如果你有一个文件中的命名空间,你肯定会需要它。 – 2010-09-02 17:43:46

1

另一种可能是: -

//div[@class='definition' or @class='example'] 

此搜索“DIV”元素,“类”的文件中的任意位置属性等于“定义”或“示例”的值。

我觉得这种方法更清楚地说明了你试图从页面中检索的内容。另一个好处是,如果页面结构发生变化,但div类保持不变,则不需要更新xpath。

您还可以使用以下非常有用的firefox插件检查您的xpath对HTML文档的作品。

Firefox Plugin - XPath Checker 0.4.4