在 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)的最佳方法是啥?