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

KJW*_*KJW 1 java xpath dom

我的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;
        }
Run Code Online (Sandbox Code Playgroud)

在我的主要文件中,我加载了一个org.w3c.dom文件,并尝试通过xpath定位一个元素:

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

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

此代码运行时会发生什么:它挂变得没有反应约30秒,然后抛出NullPointerExceptionfoundElement.

Mad*_*sen 5

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' 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]