在 PHP 中处理大型 XML 的最佳方法 [重复]

Posted

技术标签:

【中文标题】在 PHP 中处理大型 XML 的最佳方法 [重复]【英文标题】:Best way to process large XML in PHP [duplicate] 【发布时间】:2010-11-13 02:47:04 【问题描述】:

我必须在 php 中解析大型 XML 文件,其中一个是 6.5 MB,而且可能更大。 我读过的 SimpleXML 扩展将整个文件加载到一个对象中,这可能不是很有效。 根据您的经验,最好的方法是什么?

【问题讨论】:

查看Pull Parsing in PHP 我听说有人使用 XMLReader 取得了很好的成功:php.net/manual/en/book.xmlreader.php 这篇文章是关于 XMLReader 的:php.net/manual/en/book.xmlreader.php "与 SimpleXML 不同,它是一个完整的 XML 解析器,可以处理所有文档,而不仅仅是其中的一部分。与 DOM 不同,它可以处理大于可用内存的文档。不像SAX,它让您的程序处于控制之中。” 【参考方案1】:

对于大文件,您需要使用 SAX parser 而不是 DOM 解析器。

使用 DOM 解析器,它将读取整个文件并将其加载到内存中的对象树中。使用 SAX 解析器,它将顺序读取文件并调用您的用户定义的回调函数来处理数据(开始标签、结束标签、CDATA 等)

使用 SAX 解析器,您需要自己维护状态(例如,您当前所在的标签),这使得它有点复杂,但对于大文件,它会在内存方面更有效率。

【讨论】:

【参考方案2】:

我的看法:

https://github.com/prewk/XmlStreamer

一个简单的类,它将在流式传输文件时将所有子元素提取到 XML 根元素。 在来自 pubmed.com 的 108 MB XML 文件上进行了测试。

class SimpleXmlStreamer extends XmlStreamer 
    public function processNode($xmlString, $elementName, $nodeIndex) 
        $xml = simplexml_load_string($xmlString);

        // Do something with your SimpleXML object

        return true;
    


$streamer = new SimpleXmlStreamer("myLargeXmlFile.xml");
$streamer->parse();

【讨论】:

oskarth :我不知道如何使用这个类,你能不能给我一点启发?或者您可以发布完整的代码吗? 哇!在 10 分钟内,我得到了一个 4GB 的 XML 文件。和蔼可亲。 我以前使用XMLReader,但如果文档格式不正确,它会崩溃。这个类解决了问题,而且速度更快。 很高兴它对您有所帮助! @www.amitpatil.me:很抱歉,这个答案太迟了一年,但是.. 现在 github 上有一个自述文件 :) 完全没问题,我找到了自述文件。谢谢!!【参考方案3】:

当使用带有大型 XML 文件的 DOMDocument 时,不要忘记在 load() 方法的选项中传递 LIBXML_PARSEHUGE 标志。 (同样适用于DOMDocument 对象的其他load 方法)

    $checkDom = new \DOMDocument('1.0', 'UTF-8');
    $checkDom->load($filePath, LIBXML_PARSEHUGE);

(适用于 120mo XML 文件)

【讨论】:

【参考方案4】:

按照 Eric Petroelje 的建议,SAX 解析器更适合大型 XML 文件。 DOM 解析器加载整个 XML 文件并允许您运行 xpath 查询——SAX(XML 的简单 API)解析器将简单地一次读取一行并为您提供处理的挂钩点。

SAX 示例:http://www.codemiles.com/php-tutorials/php-sax-parser-in-action-t1436.html

【讨论】:

感谢您留下示例链接 :) 面向对象的例子:php-and-symfony.matthiasnoback.nl/2012/04/…【参考方案5】:

这真的取决于你想对数据做什么?您是否需要将所有内容都保存在内存中才能有效地使用它?

对于当今的计算机而言,6.5 MB 并不是那么大。例如,您可以ini_set('memory_limit', '128M');

但是,如果您的数据可以流式传输,您可能需要考虑使用SAX parser。这真的取决于您的使用需求。

【讨论】:

虽然文件本身是6.5MB,但解析后还是大了很多。我有这个20MB的xml,在调用xml_parse_into_struct时,需要将memory_limit设置为512MB,否则会失败。【参考方案6】:

SAX 解析器是要走的路。我发现如果不保持井井有条,SAX 解析会变得混乱。

我使用基于 STX(XML 流转换)的方法来解析大型 XML 文件。我使用 SAX 方法构建一个 SimpleXML 对象来跟踪当前上下文中的数据(即仅根节点和当前节点之间的节点)。然后使用其他函数来处理 SimpleXML 文档。

【讨论】:

【参考方案7】:

我需要解析一个大型 XML 文件,该文件恰好在每一行都有一个元素(*** 数据转储)。在这种特定情况下,一次读取一行文件并使用 SimpleXML 解析每一行就足够了。对我来说,这样做的好处是不必学习任何新东西。

【讨论】:

以上是关于在 PHP 中处理大型 XML 的最佳方法 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中解析大型 XML(大小为 1GB)的最佳方法是啥?

在 python 中处理大型数据集的最佳方法

在 Java 中处理 XML [重复]

使用 PHP/MySQL 导出大型 CSV 数据的最佳方法是啥?

在 PHP 中验证一个 ~400MB 的大型 XML 文件

在PHP中获取上传文件扩展名的最佳方法/实践是啥[重复]