【问题标题】:XPath expression for javax.xml.xpath not workingjavax.xml.xpath 的 XPath 表达式不起作用
【发布时间】:2016-10-05 16:13:27
【问题描述】:

我要提取这个网站的内容:https://it.projektwerk.com/de/projects/

例如我有一个 XPath 表达式:.//*[@id='content_0']/H3/A (请注意,大写字母是正确的,因为我的文档解析器 -> org.cyberneko.html ...将标签解析为那些大写字母)

这是一个有效的 XPath 表达式;例如,我可以使用 FirePath 获取内容。但是,使用javax.xml.xpath 类,检索是不可能的。我是这样做的:

XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xpath.compile(exprString);
Node node = expr.evaluate(doc, XPathConstants.NODE);

node 始终是null

我不明白这一点,因为还有其他网站具有相同语法的其他表达式,并且可以正常工作(例如 .//*[@id='p_p_id']/DIV/DIV/DIV/DIV[3]/A/H3/SPAN

希望有人能提供帮助。

【问题讨论】:

  • 通常,HTML 元素位于 HTML 命名空间中,即 URI 为 http://www.w3.org/1999/xhtml 的命名空间。您需要调用 xpath.setNamespaceContext 以使 XPath 引擎知道该命名空间,然后将您的表达式更改为类似于 .//*[@id='content_0']/html:H3/html:A
  • 感谢 VGR,它帮助我找到了解决方案,有关详细信息,请参阅下面的答案。

标签: java html xpath javax.xml


【解决方案1】:

感谢 VGR,我能够了解问题所在。那些 Xpath 表达式不起作用的网站是一个命名空间感知网站,其 html 标记构造如下:

由于我使用的是HtmlCleaner,所以我使用了以下代码:

HtmlCleaner cleaner = new HtmlCleaner();
CleanerProperties props = cleaner.getProperties();
props.setNamespacesAware(false);
TagNode mainNode = cleaner.clean(htmlString);

根据文档,应该从 html 文档中去除命名空间属性。但这并工作!令人惊讶的是,被测试的 html 文档的 html 标记内的 xmlns 属性只会改变它在属性列表中的位置。 因此解决方案是使用 html 节点的 HtmlCleaner 的 TagNode 表示手动从 htmlTag 中删除 xmlns 属性:

public TagNode removeNamespaceFromHtmlTag(TagNode htmlNode) {
    htmlNode.removeAttribute("xmlns");
    return htmlNode;
}

去掉这个,问题中定义的 XPath 表达式将返回想要的结果。

【讨论】:

    猜你喜欢
    • 2012-09-08
    • 1970-01-01
    • 1970-01-01
    • 2019-07-29
    • 1970-01-01
    • 2014-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多