gpt4 book ai didi

xpath - 使用 XPath 从具有不必要 namespace 的文档中提取 XOM 元素

转载 作者:行者123 更新时间:2023-12-03 16:12:32 25 4
gpt4 key购买 nike

我正在尝试使用 XOM 解析外部系统返回的一些 HTML。 HTML 如下所示:

<!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="en" lang="en">
<body>
<div>
Help I am trapped in a fortune cookie factory
</div>
</body>
</html>

(实际上它更困惑,但它有这个 DOCTYPE 声明和这些命名空间和语言声明,上面的 HTML 表现出与真正的 HTML 相同的问题。)

我想要做的是提取 <div>的内容,但 namespace 声明似乎混淆了 XPath。如果我去掉命名空间声明(手动,从文件中),下面的代码会找到 <div> , 没问题:
Document document = ...
Nodes divs = document.query("//div");

但是对于命名空间,返回的 Nodes大小为 0。

好吧,如果我以编程方式剥离命名空间怎么样?
Element rootElement = document.getRootElement();
rootElement.removeNamespaceDeclaration(rootElement.getNamespacePrefix());

...看起来它应该工作,但什么也不做。来自 javadoc :

This method only removes additional namespaces added with addNamespaceDeclaration.



好的,我想,我将为查询提供命名空间:
XPathContext context = 
XPathContext.makeNamespaceContext(document.getRootElement());
Nodes divs = document.query("//div", context);

大小仍然为零。

手动构建命名空间上下文怎么样?
XPathContext context = context = new XPathContext(
rootElement.getNamespacePrefix(), rootElement.getNamespaceURI());
Nodes divs = document.query("//div", context);
XPathContext构造函数爆炸:
nu.xom.NamespaceConflictException: 
XPath expressions do not use the default namespace

所以,我正在寻找:
  • 一种使此查询起作用的方法,或
  • 一种以编程方式剥离命名空间声明的方法,或
  • 对正确方法的解释,假设这两种方法都是错误的。


  • 更新:基于 Lev Levitsky's answerJaxen FAQ我想出了以下黑客:
    XPathContext context = new XPathContext(
    "foo",
    document.getRootElement().getNamespaceURI());
    Nodes divs = document.query("//foo:div");

    这对我来说仍然有点疯狂,但我想这就是 Jaxen 希望你做事的方式。

    更新 #2:如下所述和 all over the Internet ,这不是贾克森的错;它只是 XPath 是 XPath。

    所以,虽然这个 hack 有效,但我仍然想要一种剥离命名空间声明的方法。最好不要使用 XSLT。

    最佳答案

    您应该使用类似的东西直接指定命名空间

    Nodes divs = document.query("//{http://www.w3.org/1999/xhtml}div");

    或使用映射到各自命名空间的前缀(我猜这就是 NamespaceContext 的用途,但您的查询中没有前缀)。

    不幸的是,我不知道它是如何在 Java 中实现的,但如果有帮助,我可以提供一个 Python 示例。

    关于xpath - 使用 XPath 从具有不必要 namespace 的文档中提取 XOM 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9673581/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com