通过xpath直接在org.w3c.dom文档中查找节点并返回null

时间:2011-07-11 10:22:41

标签: java dom xpath

我的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;
        }

在我的主要文件中我加载了一个org.w3c.dom文件并试图通过xpath找到一个元素:

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

我已经通过firebug手动检查了使用该xpath存在的元素。

此代码运行时会发生什么:挂起变为无响应约30秒,然后为NullPointerException抛出foundElement

1 个答案:

答案 0 :(得分:5)

XHTML文档是一个带有DTD引用的XML文档,XML解析器必须下载和评估这些文档才能正确解析XML信息集,并且元素绑定到XHTML命名空间。

所以,看来你有两个问题:

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

      

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

         

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

    您可以通过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. 文档中的元素绑定到XHTML命名空间,但您使用的是与默认无命名空间匹配的XPath。

    您可以采取以下措施来确保您的XPath符合您的要求

    • 使用XPath引擎注册XHTML名称空间,并调整XPath表达式以使用已注册的XHTML名称空间前缀。
    • 使用与XHTML命名空间匹配的XPath语句和谓词过滤器内的本地名称,以便对元素进行更通用的匹配,例如: /*[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]
    • 使用与本地名称匹配的XPath语句,以便在元素上进行更通用的匹配。例如/*[local-name()='html'][1]/*[local-name()='body'][1]/*[local-name()='div'][32]/*[local-name()='a'][1]