【问题标题】:Unclear results with jdom2 XPath query [duplicate]jdom2 XPath 查询的结果不清楚 [重复]
【发布时间】:2013-12-21 09:36:01
【问题描述】:

我对 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

它必须是带有名称空间的东西或标题中的任何其他东西,因为没有它它可以生成一些输出。我不知道我做错了什么。

【问题讨论】:

  • “它必须是带有命名空间的东西” - 正确。我链接到的“可能重复”问题是谷歌给我的“jdom xpath 命名空间”的第一个命中
  • 现在似乎已解决 - 更改:命名空间 namespace = Namespace.getNamespace("my","w3.org/1999/xhtml"); 和 XPathExpression xp = xpfac.compile("//my:a[@ class= 'nextpage']", Filters.element(),null,namespace);
  • 这个问题似乎离题了,因为它现在已经解决了(请参阅 OP 的评论)。
  • 您应该将该评论转化为答案(SO 让您可以回答自己的问题)并将答案标记为已接受,以便其他人可以看到问题已解决。
  • 由于此代码使用 JDOM 2.x 并且指示的重复使用 JDOM1.x(它们在处理 XPath 的方式上非常不同),所以这不是重复...

标签: java xpath jdom-2


【解决方案1】:

注意:尽管这与建议的副本中描述的问题相同,但其他问题与 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 为空(这是相同的方式属性名称被扩展)。如果 QName 具有在表达式上下文中没有命名空间声明的前缀,则会发生错误。

实际上,这意味着,只要您在 XML 文档中有一个“默认”命名空间,在 XPath 表达式中使用它时,您仍然需要为该命名空间添加前缀。 XPathFactory.compile(...) 方法暗示了这个要求in the JavaDoc,但它并不像应有的那样清楚。您使用的前缀是任意的,并且仅限于该 XPath 表达式。在您的情况下,代码将类似于(假设我们为 URI http://www.w3.org/1999/xhtml 选择命名空间 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"));
}

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

【讨论】:

    猜你喜欢
    • 2014-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-02
    • 2013-06-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多