2009-07-22 11 views
26

PHPで大規模なXMLファイルを解析する必要があります.1つは6.5 MBであり、さらに大きくなる可能性があります。 私が読んだようなSimpleXML拡張は、ファイル全体をオブジェクトに読み込みますが、これはあまり効率的ではありません。 あなたの経験では、何が最善の方法でしょうか?PHPで大規模なXMLを処理する最良の方法

+0

チェックアウト([PHPで解析を引い] http://www.ibm.com/(同じことがDOMDocumentオブジェクトの他のload方法に適用されます) developerWorks/xml/library/x-pullparsingphp/index.html) – Randolpho

+0

この記事はXMLReaderに関するものです: http://php.net/manual/en/book.xmlreader.php "SimpleXMLとは異なり、これは完全なXMLパーサで、 DOMとは異なり、利用可能なメモリよりも大きなドキュメントを扱うことができます。SAXとは異なり、プログラムを制御します。 – WayFarer

+0

私はXMLReaderで成功した人がいると聞いています:http://php.net/manual/en/book.xmlreader.php – Steven

答えて

21

大きなファイルの場合は、DOMパーサーではなくSAX parserを使用します。

DOMパーサーでは、ファイル全体を読み込み、メモリ内のオブジェクトツリーに読み込みます。 SAXパーサーを使用すると、ファイルを順番に読み込み、データ(開始タグ、終了タグ、CDATAなど)を処理するためのユーザー定義のコールバック関数を呼び出します。

SAXパーサーを使用すると、あなたが現在使っているタグのように自分自身を少し複雑にしていますが、大きなファイルの場合にはメモリの方がはるかに効率的です。

3

本当にデータをどうしたいのですか?あなたは効果的にそれを使用するためにすべてのメモリを必要としますか?

6.5 MBは今日のコンピュータの点でそれほど大きくありません。あなたのデータをストリーミングすることができる場合は、例えば、ini_set('memory_limit', '128M');

しかし、あなたはSAX parserを使用して見てみたいことがあります。それは本当にあなたの使用ニーズに依存します。

+3

ファイル自体は6.5MBですが、解析後にははるかに大きくなります。私はこの20MBのxmlを持っていました、 'xml_parse_into_struct'を呼び出すときに、memory_limitを512MBに設定する必要があります。そうしないと、失敗します。 – faulty

6

SAXパーサーは、Eric Petroeljeが推奨するように、大きなXMLファイルの方が適しています。 DOMパーサはXMLファイル全体にロードされ、xpathクエリを実行することができます。つまり、SAX(XML for Simple API)パーサーは一度に1行ずつ読み込み、処理のフックポイントを与えます。

+0

例のリンクを残してくれてありがとう:) –

+0

オブジェクト指向の例:http://php-and-symfony.matthiasnoback.nl/2012/04/php-create-an-object-oriented-xml-parser-using-the-組み込み-xml_-functions/ –

1

SAXパーサを移動するための方法です。私はあなたが整理されたままでいなければ、SAXの構文解析が面倒なことがあることを発見しました。

大規模なXMLファイルを解析するために、STX(XML用ストリーミング変換)に基づくアプローチを使用します。私はSAXメソッドを使用して、現在のコンテキスト(つまり、ルートノードと現在のノードの間のノードのみ)のデータを追跡するSimpleXMLオブジェクトを構築します。次に、SimpleXMLドキュメントを処理するために他の関数が使用されます。

1

各行(StackOverflowデータダンプ)に要素があるようになった大きなXMLファイルを解析する必要がありました。この特定のケースでは、一度に1行ずつファイルを読み取り、SimpleXMLを使用して各行を解析するだけで十分でした。私にとっては、これは新しいことを学ぶ必要がないという利点がありました。

11

それが私の感想:

https://github.com/prewk/XmlStreamer

ファイルをストリーミングしながら、XMLのルート要素にすべての子を抽出する単純なクラスです。 pubmed.comの108 MBのXMLファイルでテストされています。大規模なXMLファイルでDOMDocumentを使用する場合は

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(); 
+0

oskarth:私はこのクラスの使い方を知りません。あなたは私を少し啓発しますか?または、完全なコードを投稿できますか? –

+4

うわー! 10分後に私は4GBのXMLファイルを作成しました。 Genial。 – Slawa

+0

以前は 'XMLReader'を使っていましたが、文書が整形式でないとクラッシュしました。このクラスは問題を解決し、はるかに高速です。 – Drahcir

7

load()方法の選択肢にLIBXML_PARSEHUGEフラグを渡すことを忘れないでください。

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

(120moのXMLファイルで動作します)

関連する問題