通过 xpath 在 org.w3c.dom 文档中查找节点永远需要并返回 null

发布于 2024-11-19 19:05:29 字数 666 浏览 2 评论 0原文

我的 XpathUtility 类具有以下方法:

public Node findElementByXpath(Document doc, String axpath) throws Exception{
            XPath xPath = XPathFactory.newInstance().newXPath();
            Node node = (Node) xPath.evaluate(axpath, doc, XPathConstants.NODE);
            return node;
        }

在我的 main 中,我加载 org.w3c.dom 文档并尝试通过 xpath 定位元素:

XpathUtility xu = new XpathUtility();
Node foundElement= xu.findElementByXpath(domdoc, "/html[1]/body[1]/div[32]/a[1]");

我已通过 firebug 手动检查该元素是否存在使用该 xpath。

此代码运行时会发生什么情况:它挂起并无响应大约 30 秒,然后抛出 foundElementNullPointerException

My XpathUtility class has following method:

public Node findElementByXpath(Document doc, String axpath) throws Exception{
            XPath xPath = XPathFactory.newInstance().newXPath();
            Node node = (Node) xPath.evaluate(axpath, doc, XPathConstants.NODE);
            return node;
        }

in my main I load a org.w3c.dom document and attempt to locate an element via xpath:

XpathUtility xu = new XpathUtility();
Node foundElement= xu.findElementByXpath(domdoc, "/html[1]/body[1]/div[32]/a[1]");

I have checked manually via firebug that element exists using that xpath.

What happens when this code runs: it hangs becomes unresponsive for about 30 seconds and then throws NullPointerException for foundElement.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

停滞 2024-11-26 19:05:29

XHTML 文档是带有 DTD 引用的 XML 文档,XML 解析器必须下载并评估该文档,以便正确解析 XML 信息集,并且元素绑定到 XHTML 命名空间。

因此,看来您有两个问题:

  1. XHTML DTD 需要很长时间才能完成从 W3C 网站下载

    <块引用>

    W3C 服务器返回 DTD 的速度很慢。是否有延迟
    故意的吗?

    是的。由于各种软件系统从我们的网站下载 DTD
    每天数百万次(尽管我们的缓存指令
    服务器),我们已经开始从我们的网站提供 DTD
    人为拖延。我们这样做的目的是让更多人关注
    我们持续存在 DTD 流量过多的问题,并保护
    我们网站其他部分的稳定性和响应时间。

    您可以通过使用本地实体解析器来克服这个问题加载 DTD 的本地副本,而不是在每次请求时都访问 W3C 网站

  2. 文档中的元素绑定到 XHTML 命名空间,但您使用的 XPath 与默认值无命名空间。

    您可以采取多种措施来确保您的 XPath 与您想要的相符

    • 使用 XPath 引擎注册 XHTML 命名空间,并调整 XPath 表达式以使用注册的 XHTML 命名空间前缀。
    • 使用与 XHTML 命名空间和谓词过滤器内的本地名称匹配的 XPath 语句,对元素进行更通用的匹配,例如 /*[local-name()='html' 和 namespace-uri( )='www.w3.org/1999/xhtml/'][1]/*[local-name()='body' 和namespace-uri()='www.w3.org/1999/xhtml/'][1]/*[local-name()='div' 和 namespace-uri()='www.w3.org/1999/ xhtml/'][32]/*[local-name()='a' 和 namespace-uri()='www.w3.org/1999/xhtml/'][1]
    • 使用仅匹配本地名称的 XPath 语句,以对元素进行更通用的匹配。例如 /*[local-name()='html'][1]/*[local-name()='body'][1]/*[local-name()='div'][ 32]/*[local-name()='a'][1]

An XHTML document is an XML document with a DTD reference, which XML parsers are obliged to download and evaluate in order to properly parse the XML infoset, and the elements are bound to the XHTML namespace.

So, it appears that you have two problems:

  1. The XHTML DTD is taking a really long time to download from the W3C website.

    The W3C servers are slow to return DTDs. Is the delay
    intentional?

    Yes. Due to various software systems downloading DTDs from our site
    millions of times a day (despite the caching directives of our
    servers), we have started to serve DTDs from our site with an
    artificial delay. Our goals in doing so are to bring more attention to
    our ongoing issues with excessive DTD traffic, and to protect the
    stability and response time of the rest of our site.

    You can overcome this by using a local entity resolver that loads a local copy of the DTD, rather than reaching out to the W3C website on every request.

  2. The elements in the document are bound to the XHTML namespace, but you are using an XPath that is matching on the default no-namespace.

    There are several things that you can do to ensure that your XPath matches what you want:

    • Register the XHTML namespace with your XPath engine and adjust your XPath expressions to use the registered XHTML namespace prefix.
    • Use an XPath statement that matches on the XHTML namespace and the local name inside of a predicate filter for a more generic match on elements e.g. /*[local-name()='html' and namespace-uri()='www.w3.org/1999/xhtml/'][1]/*[local-name()='body' and namespace-uri()='www.w3.org/1999/xhtml/'][1]/*[local-name()='div' and namespace-uri()='www.w3.org/1999/xhtml/'][32]/*[local-name()='a' and namespace-uri()='www.w3.org/1999/xhtml/'][1]
    • Use an XPath statement that simply matches on the local name for a more generic match on elements. e.g. /*[local-name()='html'][1]/*[local-name()='body'][1]/*[local-name()='div'][32]/*[local-name()='a'][1]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文