-->

验证大型XML文件〜在PHP 400MB(Validating a large XML file ~

2019-08-04 01:34发布

我有一个大的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杀手不沾它的脂肪鼻子和杀死我的过程。

没有人有任何经验,验证大型XML文件和捕捉的在那里的严重错误形成,很多帖子我读过点SAX和XMLReader的可能解决我的问题。

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

当使用SimpleXML ...它能够捕捉到大部分的问题在文件中,并显示在我这是很好的结束。

Answer 1:

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

Adpating从代码示例页面 ,它看起来是这样的:

 $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); 


Answer 2:

对于大文件,完美的使用XMLReader类。

但是,如果喜欢simplexml的语法: https://github.com/dkrnl/SimpleXMLReader/blob/master/library/SimpleXMLReader.php用例: http://github.com/dkrnl/SimpleXMLReader/blob/master/examples/example1。 PHP



文章来源: Validating a large XML file ~400MB in PHP