如何从大于可用RAM的xml文件中删除xml元素/节点


How to delete xml elements/nodes from xml file larger than available RAM?

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

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

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

我发现的最接近的东西是这个(C#):

您可以使用 XmlReader 按顺序读取 xml(在您的情况下,一次读取整个节点的 ReadOuterXml 可能很有用)。然后使用 XmlWriter 写出要保留的所有节点。(从大型XML文件中删除节点)

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

真的没有别的办法吗?

一个approcah

正如建议的那样,

我可以使用phps XML阅读器或解析器读取数据,可能缓冲它,并将其写入/转储+追加回新文件。

但这种方法真的实用吗?

我有将大型xml文件拆分为较小部分的经验,基本上使用建议的方法,并且该过程需要很长时间才能完成。

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

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

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

  1. PHP 有一个拉取解析器的XMLReader实现。解释:

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

  2. 或者,您可以使用 SAX XML 解析器。解释:

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

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