【问题标题】:Java, XPath on DOM nodeJava,DOM 节点上的 XPath
【发布时间】:2013-02-06 04:41:13
【问题描述】:

我想将一个非常大的 XML 文件加载到 DOM 树中(使用 JAXP),进行一些修改并在生成的 DOM 上运行 XPath 查询。

我们使用我们自己的 DOM 实现,该实现是使用延迟加载实现的(即,一开始只从文件中加载前两级 DOM,如果调用 getChildNodes()/etc.,我们将返回文件并加载更多关卡)。这很慢,但是,我们能够加载更大的文件,尤其是如果我们只使用文件的一部分。

我的问题:XPath 在 XML (afaik) 上使用了不同的视图。我很好奇默认的 Oracle JDK 实现现在是否正在将整个 DOM 文档转换为一些内部 XPath 文档(这真的很糟糕,因为它会急切地加载整个文档),或者 XPath 实现是否能够直接在我们的DOM 树(即,如果 XPath 可以在已加载的元素中进行评估,则无需进一步加载)。

【问题讨论】:

  • 你说的非常大是什么意思?如果您查看运行时的内存消耗,您的问题不会得到回答吗?
  • 为什么您认为 XPath 使用的不是 DOM? FWIW,我看到至少有一个错误表明它以常规形式使用 DOM(该错误涉及使用基于树深处的上下文进行搜索来遍历整个 DOM)。
  • 规范没有提到 DOM 作为底层模型,而 Apache Xalan-J 实现(在 Oracle JDK 中使用的 afaik)似乎使用了某种 DTM (xml.apache.org/xalan-j/dtm.html)。但是,我无法确定 DOM 是完全转换为 DTM 还是仅是评估 XPathExpression 所需的特定部分,或者 DTM 是否只是 DOM 的适配器。
  • @parsifal:请参阅下面的答案,不幸的是,最常用的 XPath 实现是在评估 XPath 之前(急切地)将整个 DOM 转换为内部格式 - 即使 XPath 只是 /root,首先转换整个文档... :(

标签: java xml dom xpath


【解决方案1】:

这可以用几行代码进行测试,只需将您的 DOM 提供给 XPath 评估器,并在您的 DOM 方法中放置一些断点/调试打印。如果它们被调用以获取不应检索的元素,则它会构建自己的树。示例:尝试只查询文档的第一个孩子,看看它实际上会尝试检索什么。

如果您的文件太大,您还可以检查完全不同的方法吗?叫SAX

【讨论】:

  • 我一直在撒谎:我们的惰性 DOM 实现还没有实现,我们目前正在研究是否有可能在后面使用惰性 DOM 树(例如通过 XPath,其中其他访问方法)。所以我很好奇是否有人知道默认的 JDK XPath 实现。我猜 DOM 树上的 XPath 将是一个常规案例。
【解决方案2】:

我们的 DOM 实现现已完成,因此我现在可以测试:

不幸的是,官方的 JDK 实现以及当前的 Xalan-J 实现都在评估路径之前将整个 DOM 树转换为内部数据结构。

即使你没有惰性 DOM 实现,这也应该很糟糕,无论如何这真的很糟糕......

【讨论】:

    猜你喜欢
    • 2012-03-01
    • 1970-01-01
    • 2010-11-10
    • 2012-07-29
    • 2012-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-09
    相关资源
    最近更新 更多