【问题标题】:How to delete xml elements/nodes from xml file larger than available RAM?如何从大于可用 RAM 的 xml 文件中删除 xml 元素/节点?
【发布时间】:2012-08-08 17:00:08
【问题描述】:

我正在尝试弄清楚如何从 php(最新版本)中非常大的 xml 文件中删除一个元素(及其子项)。

我知道我可以使用 dom 和 simpleXml,但这需要将文档加载到内存中。

我正在查看 XML 编写器/读取器/解析器函数和谷歌搜索,但似乎没有关于该主题的内容(所有答案都建议使用 dom 或 simpleXml)。这不可能是正确的——我错过了什么吗?

我找到的最接近的东西是这个(C#):

您可以使用 XmlReader 顺序读取您的 xml(ReadOuterXml 在您的情况下一次读取整个节点可能很有用)。然后使用 XmlWriter 写出您要保留的所有节点。 (Deleting nodes from large XML files)

真的吗?那是方法吗?我必须复制整个大文件吗?

真的没有别的办法了吗?

一个方法

按照建议,

我可以使用 phps XML 阅读器或解析器读取数据,可能会对其进行缓冲,然后将其写入/转储+追加到新文件中。

但是这种方法真的实用吗?

我有将大型 xml 文件拆分成小块的经验,基本上是使用建议的方法,但这个过程需要很长时间才能完成。

我的数据集目前还不够大,无法让我知道如何解决这个问题。我只能假设结果将是相同的(一个非常缓慢的过程)。

有人有在实践中应用这个的经验吗?

【问题讨论】:

  • XML 文件的大小是否比您的 RAM 大?
  • 假设是的。我试图找出一种方法来处理大型 xml 结构,并且假设如果当前大小不大于内存,它最终会。

标签: php xml


【解决方案1】:

有几种方法可以增量处理大型文档,这样您就不需要一次将整个结构加载到内存中。无论哪种情况,是的,您需要写回您希望保留的元素并省略您想要删除的元素。

  1. PHP 有一个XMLReader implementation of a pull parser。一个explanation:

    拉式解析器创建一个迭代器,该迭代器依次访问各种 XML 文档中的元素、属性和数据。使用的代码 这个迭代器可以测试当前项目(例如,告诉 它是一个开始或结束元素,或文本),并检查其属性 (本地名称、命名空间、XML 属性值、文本值、 等),并且还可以将迭代器移动到下一个项目。代码可以 从而在文档遍历时从文档中提取信息。

  2. 或者你可以使用the SAX XML Parser。 Explanation:

    Simple API for XML (SAX) 是一个词法、事件驱动的接口,其中 连续读取文档,并将其内容报告为回调 到用户设计的处理程序对象上的各种方法。 SAX 是 实现快速高效,但难以用于提取 从 XML 中随机获取信息,因为它往往会给 跟踪文档的哪一部分的应用程序作者 正在处理中。

很多人更喜欢 pull 方法,但两者都符合您的要求。请记住,大是相对的。如果文档适合内存,那么使用 DOM 几乎总是更容易。但是对于非常非常大的文档,可能根本不是一种选择。

【讨论】:

  • 我已经搜索和搜索,但似乎这是在 php 中执行此操作的唯一方法。我暂时必须这样做,但是当文件开始达到 gb 大小时,我仍然感到不安。在出现更好的方法之前,我将接受您的答案作为公认的解决方案 =)
  • 这不仅仅是在 PHP 中实现它的唯一方法。 SAX 解析所需的内存与树的深度成正比,通常比整个文档的大小要小得多。
  • 我不明白。你能再解释一下吗?请记住,假设内存不足以满足进程。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-13
  • 1970-01-01
  • 2013-02-19
  • 2019-04-12
  • 2018-07-01
  • 2010-09-12
相关资源
最近更新 更多