微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

我有一个大的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)都会导致一些对我来说是“新鲜杀手”的东西,在看起来像是30秒之后终止脚本.

我以为我可能需要增加脚本的内存,以便在处理60MB时找出峰值使用量,并相应地调整大小,并且还会关闭脚本时间限制以防万一.

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

不幸的是,这不起作用,因为如果内存负载(即使是正确的术语?)一直很高,那么oom杀手似乎是一个linux的东西.

如果我能以某种方式加载xml,这将是很好的,因为我想这将减少内存负载,以便oom杀手不会坚持它的肥胖鼻子并杀死我的过程.

有没有人有任何验证大型XML文件和捕获错误形成错误的经验,我读过很多帖子都指向可能解决我问题的SAX和XMLReader.

UPDATE
所以@chiborg对我来说几乎解决了这个问题…这个方法唯一的缺点就是我没有看到文件中的所有错误,只是第一个失败,我认为这是有意义的,因为我认为它无法解析失败的第一个点.

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

解决方法:

由于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);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐