2013-12-21 56 views
1

我有jdom2 XPath的问题:与jdom2 XPath查询结果不明

test.xhtml代码:

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="cs" lang="cs"> 
<head> 
<title>mypage</title> 
</head> 
<body> 
<div class="in"> 
<a class="nextpage" href="url.html"> 
<img src="img/url.gif" alt="to url.html" /> 
</a> 
</div> 
</body> 
</html> 

Java代码:

Document document; 
SAXBuilder saxBuilder = new SAXBuilder(); 

document = saxBuilder.build("test2.html"); 
XPathFactory xpfac = XPathFactory.instance(); 
XPathExpression<Element> xp = xpfac.compile("//a[@class = 'nextpage']", Filters.element()); 
for (Element att : xp.evaluate(document)) { 
    System.out.println("We have target " + att.getAttributeValue("href")); 
} 

但只是这个我不能得到任何元素。我发现当查询是//*[@class = 'nextpage']时,它发现它。

We have target url.html 

它必须是一些与命名空间或以其他任何标题,因为没有它,它可以产生一些输出。我不知道我做错了什么。

+0

“它必须是具有名称空间的东西” - 正确。我已经链接到的“可能重复”问题是谷歌给我的第一个命令“jdom xpath namespace” –

+0

现在似乎已经解决 - changes:Namespace namespace = Namespace.getNamespace(“my”,“http://www.w3 .ORG/1999/XHTML“);和XPathExpression xp = xpfac.compile(“// my:a [@class ='nextpage']”,Filters.element(),null,namespace); – d3im

+1

这个问题似乎是脱离主题,因为它现在已经_solved_(见OP的评论)。 – devnull

回答

0

注意:尽管这与建议的重复项中描述的问题相同,但其他问题与JDOM版本1.x有关。在JDOM 2.x中有很多重要的区别。这个答案与JDOM 2.x XPath实现which is significantly different有关。

XPath规范非常清楚如何在XPath表达式中处理名称空间。不幸的是,对于熟悉XML的人来说,命名空间的XPath处理与他们的期望略有不同。 This is the specification

节点测试中的QName使用来自表达式上下文的名称空间声明扩展为扩展名。这与扩展在开始和结束标签中的元素类型名称的扩展方式相同,只是不使用用xmlns声明的默认名称空间:如果QName没有前缀,则名称空间URI为null(这是相同的方式属性名称被扩展)。如果QName的前缀没有在表达式上下文中存在名称空间声明,那是错误的。

实际上,这意味着,只要在XML文档中有'默认'命名空间,在XPath表达式中使用该命名空间时,仍然需要为该名称空间添加前缀。 XPathFactory.compile(...)方法暗示了这个要求in the JavaDoc,但它不像它应该那样清晰。您使用的前缀是任意的,并且仅限于该XPath表达式的本地。在你的情况下,代码会看起来像(假设我们选择的命名空间xhtml的URI http://www.w3.org/1999/xhtml):

XPathFactory xpfac = XPathFactory.instance(); 
Namespace xhtml = Namespace.getNamespace("xhtml", "http://www.w3.org/1999/xhtml"); 
XPathExpression<Element> xp = xpfac.compile("//xhtml:a[@class = 'nextpage']", Filters.element(), null, xhtml); 
for (Element att : xp.evaluate(document)) { 
    System.out.println("We have target " + att.getAttributeValue("href")); 
} 

我应该将其添加到常见问题解答...谢谢。