5

大きな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 killer」という新しいものが発生し、常に30秒のように見える後にスクリプトが起動して終了します。

スクリプトのメモリを増やす必要があるかもしれないと思ったので、60MBを処理するときのピーク使用量を計算し、それに応じて大きく調整し、万が一の場合に備えてスクリプトの時間制限をオフにしました。

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

残念ながら、これは機能しませんでした。oomkillerは、メモリ負荷(適切な用語でさえも)が一貫して高い場合に起動するLinuxのものであるように見えるためです。

何とかしてxmlをチャンクでロードできれば、メモリの負荷が減り、oomkillerがファットノーズを突き刺してプロセスを強制終了しないようになると思います。

誰かが大きなXMLファイルを検証し、それが正しく形成されていない場所のエラーをキャプチャした経験はありますか?私が読んだ多くの投稿は、私の問題を解決する可能性のあるSAXとXMLReaderを指しています。

更新 したがって、@ chiborgは私にとってこの問題をほぼ解決しました...この方法の唯一の欠点は、ファイル内のすべてのエラーを確認できないことです。最初に失敗したものだけが、私が思うに理にかなっていると思います。失敗した最初のポイントを超えて解析することはできません。

simplexmlを使用すると、ファイル内のほとんどの問題をキャプチャして、最後に表示することができます。これはすばらしいことです。

4

2 に答える 2

6

SimpleXMLおよびDOMAPIは常にドキュメントをメモリにロードするため、SAXやXMLReaderなどのストリーミングパーサーを使用することをお勧めします。

サンプルページのコードを適用すると、次のようになります

$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);
于 2012-12-13T11:04:44.947 に答える
0

大きなファイルの場合は、XMLReaderクラスを使用してください。

ただし、simplexml構文が気に入った場合:https ://github.com/dkrnl/SimpleXMLReader/blob/master/library/SimpleXMLReader.php 使用例: http://github.com/dkrnl/SimpleXMLReader/blob/master/examples/example1 。 php

于 2013-11-11T06:28:59.823 に答える