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

Posted

技术标签:

【中文标题】在 PHP 中验证一个 ~400MB 的大型 XML 文件【英文标题】:Validating a large XML file ~400MB in PHP 【发布时间】:2012-12-01 05:43:05 【问题描述】:

我有一个大型 XML 文件(大约 400MB),在开始处理之前我需要确保它格式正确。

我尝试的第一件事类似于下面的内容,这很好,因为我可以找出 XML 是否格式不正确以及 XML 的哪些部分是“坏的”

$doc = simplexml_load_string($xmlstr);
if (!$doc) 
    $errors = libxml_get_errors();

    foreach ($errors as $error) 
        echo display_xml_error($error);
    

    libxml_clear_errors();

也试过了……

$doc->load( $tempFileName, LIBXML_DTDLOAD|LIBXML_DTDVALID )

我用一个大约 60MB 的文件对此进行了测试,但是任何更大的文件 (~400MB) 都会导致对我来说是新的“oom 杀手”的东西在似乎总是 30 秒后启动并终止脚本。

我认为我可能需要增加脚本上的内存,因此在处理 60MB 时计算出峰值使用量并相应地调整它,并关闭脚本时间限制以防万一。

set_time_limit(0);
ini_set('memory_limit', '512M');

不幸的是,这并没有奏效,因为如果内存负载(即使是正确的术语?)一直很高,oom 杀手似乎是一个 linux 的东西。

如果我能以某种方式以块的形式加载 xml,那就太好了,因为我想这会减少内存负载,这样 oom Killer 就不会把它的肥鼻子塞进去并杀死我的进程。

有没有人有任何验证大型 XML 文件并捕获其格式错误的错误的经验,我读过的很多帖子都指向 SAX 和 XMLReader,它们可能会解决我的问题。

更新 所以@chiborg 几乎为我解决了这个问题......这种方法的唯一缺点是我看不到文件中的所有错误,只是第一个失败的错误,我认为这是有道理的,因为我认为它无法解析失败的第一个点。

当使用 simplexml...它能够捕获文件中的大部分问题并在最后向我展示这很好。

【问题讨论】:

SimpleXML 扩展是一个简单的 XML 工具。它将所有内容加载到内存中,并且不是为大文件设计的。无论您喜欢与否,都必须使用 XMLReader 对其进行验证。 您是否只有一个 XML 文件,或者您是否经常获得这种大小的 XML 文件? 定期获取文件,但我处理的大多数文件会更小,因此我希望实施一个解决方案来涵盖我最坏的情况,并知道未来的 oom 杀手不会成为问题跨度> 【参考方案1】:

由于 SimpleXML 和 DOM API 总是将文档加载到内存中,因此使用像 SAX 或 XMLReader 这样的流解析器是更好的方法。

修改example page中的代码,它可能看起来像这样:

$xml_parser = xml_parser_create();
if (!($fp = fopen($file, "r"))) 
    die("could not open XML input");


while ($data = fread($fp, 4096)) 
    if (!xml_parse($xml_parser, $data, feof($fp))) 
        $errors[] = array(
                    xml_error_string(xml_get_error_code($xml_parser)),
                    xml_get_current_line_number($xml_parser));
    

xml_parser_free($xml_parser);

【讨论】:

【参考方案2】:

对于大文件,最好使用 XMLReader 类。

但如果喜欢 simplexml 语法:https://github.com/dkrnl/SimpleXMLReader/blob/master/library/SimpleXMLReader.php 使用示例:http://github.com/dkrnl/SimpleXMLReader/blob/master/examples/example1.php

【讨论】:

以上是关于在 PHP 中验证一个 ~400MB 的大型 XML 文件的主要内容,如果未能解决你的问题,请参考以下文章

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

Bentley.Hammer.XM.v08.09.400.34 1CD(水锤和瞬态分析软件)好用版

如何提高大型文本文件的数据加载性能[重复]

Bentley.Hammer.XM.v08.09.400.34 1CD(水锤和瞬态分析软件)好用版

在 Python 中保存和加载大型字典的最快方法

Laravel - 超过 PHP 最大上传大小限制时验证文件大小