27

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

4

7 回答 7

23

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

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

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

于 2009-07-22T17:58:43.400 回答
11

我的看法:

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();
于 2011-11-23T23:06:36.753 回答
8

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

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

(适用于 120mo XML 文件)

于 2014-01-23T17:24:59.170 回答
6

正如 Eric Petroelje 所推荐的那样,SAX 解析器对于大型 XML 文件会更好。DOM 解析器加载整个 XML 文件并允许您运行 xpath 查询——SAX(XML 的简单 API)解析器将简单地一次读取一行并为您提供处理的挂钩点。

于 2009-07-22T18:14:31.730 回答
3

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

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

但是,如果您的数据可以流式传输,您可能需要考虑使用SAX 解析器。这实际上取决于您的使用需求。

于 2009-07-22T18:00:24.770 回答
2

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

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

于 2009-07-22T18:26:48.850 回答
1

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

于 2010-03-10T09:41:46.527 回答