2013-08-29 13 views
5

私は次のような助けが必要です。PHPで4 GBのXMLファイルをストリーム解析する

PHPで大きなXMLファイル(4 GB)をストリーム解析したいと思います。単純なXMLやDOMを使うことはできません。なぜなら、ファイル全体をメモリに読み込むので、ファイルをストリームできるものが必要なのです。

PHPでこれを行うにはどうすればよいですか?

私がしようとしているのは、一連の<doc>要素をナビゲートすることです。また、いくつかの子を新しいxmlファイルに書き込んでください。

私はこのようなルックスを解析しようとしているXMLファイル:

<feed> 
    <doc> 
     <title>Title of first doc is here</title> 
     <url>URL is here</url> 
     <abstract>Abstract is here...</abstract> 
     <links> 
      <sublink>Link is here</sublink> 
      <sublink>Link is here</sublink> 
      <sublink>Link is here</sublink> 
      <sublink>Link is here</sublink> 
      <sublink>Link is here</sublink> 
     </link> 
    </doc> 
    <doc> 
     <title>Title of second doc is here</title> 
     <url>URL is here</url> 
     <abstract>Abstract is here...</abstract> 
     <links> 
      <sublink>Link is here</sublink> 
      <sublink>Link is here</sublink> 
      <sublink>Link is here</sublink> 
      <sublink>Link is here</sublink> 
      <sublink>Link is here</sublink> 
     </link> 
    </doc> 
</feed> 

私が取得/ <links>要素とその子供たちを除いて新しいXMLファイルに各<doc>要素のすべての子をコピーしようとしています。

<doc> 
    <title>Title of first doc is here</title> 
    <url>URL is here</url> 
    <abstract>Abstract is here...</abstract> 
</doc> 
<doc> 
    <title>Title of second doc is here</title> 
    <url>URL is here</url> 
    <abstract>Abstract is here...</abstract> 
</doc> 

は、私は非常にストリーミング/ストリームのパース/ストリームオリジナルのXMLファイルを読み込み、その内容の一部を書面で任意およびすべてのヘルプをいただければ幸いです。

は、だから私は次のように新しいXMLファイルを見てみたいですPHPの新しいXMLファイルに変換します。

+3

は、XmlReaderクラスをチェックアウト: //www.php.net/manual/en/intro.xmlreader.phpストリーミングパーサーです。より具体的な回答をお手伝いできるかどうかを知るために、あなたの質問をもっと深く読んでいます。 – DeeDee

+0

@DeeDee XMLReaderについて聞いたことがありますが、XMLReaderの使い方は分かりませんでした。お手伝いありがとう! –

+0

公式文書のコメントが不足していることからも分かるように、あまり使われていません。私は自分自身を非常に長い間使っていません。私のコードの仕組みを教えていただけますか?すぐに機能しない場合は、協力して何が起きているか把握することができます。 – DeeDee

答えて

4

ここでは、大学の試しです。これは、ファイルが使用されている、とあなたは、ファイルへの書き込みをすることを前提としています。あなたが述べたように、DOMパーサを使用している余裕はありません。このシナリオでは

<?php 

$interestingNodes = array('title','url','abstract'); 
$xmlObject = new XMLReader(); 
$xmlObject->open('bigolfile.xml'); 

$xmlOutput = new XMLWriter(); 
$xmlOutput->openURI('destfile.xml'); 
$xmlOutput->setIndent(true); 
$xmlOutput->setIndentString(" "); 
$xmlOutput->startDocument('1.0', 'UTF-8'); 

while($xmlObject->read()){ 
    if($xmlObject->name == 'doc'){ 
     $xmlOutput->startElement('doc'); 
     $xmlObject->readInnerXML(); 
     if(array_search($xmlObject->name, $interestingNodes)){ 
      $xmlOutput->startElement($xmlObject->name); 
      $xmlOutput->text($xmlObject->value); 
      $xmlOutput->endElement(); //close the current node 
     } 
     $xmlOutput->endElement(); //close the doc node 
    } 
} 

$xmlObject->close(); 
$xmlOutput->endDocument(); 
$xmlOutput->flush(); 

?> 
+0

最新の編集内容は何ですか?私はこれと現在のバージョンと私が以前読んでいたバージョンとの違いは分かりません。 –

+0

これは私が探していたもののようです。ありがとうございます。私は今夜​​後にそれを試し、何が起こるかを教えてくれるでしょう。 –

+0

私は '<?php'タグを閉じました – DeeDee

0

、それがメモリに起因する納まりませんあなたができる場合でも、ファイル全体を最初にロードするときには遅くなり、その後は反復処理が必要になるので、この場合はSAXパーサ(イベント/ストリーム指向)を試してみてください。関心のあるタグ(doctitleurlabstract)のハンドラを追加し、すべてのイベントに対して新しいXMLファイルにあるノードを追加します。ここで

あなたはより多くの情報を持っている:ここでは

What is the fastest XML parser in PHP?

は、コードがどうなるかの(をテストしていません)サンプル次のとおりです。http:

<?php 
    $file = "bigfile.xml"; 
    $fh = fopen("out.xml", 'a') or die("can't open file"); 
    $currentNodeTag = "";  
    $tags = array("doc", "title", "url", "abstract"); 

    function startElement($parser, $name, $attrs) { 
     global $tags; 

     if (isset($tags[strtolower($name)])) { 
      $currentNodeTag = strtolower($name); 
      fwrite($fh, sprintf("<%s>\n")); 
     } 
    } 

    function endElement($parser, $name) { 
     global $tags; 

     if (isset($tags[strtolower($name)])) { 
      fwrite($fh, sprintf("</%s>\n")); 
      $currentNodeTag = ""; 
     } 
    } 

    function characterData($parser, $data) { 
     if (!empty($currentNodeTag)) { 
      fwrite($fh, $data); 
     } 
    }  

    $xmlParser = xml_parser_create(); 
    xml_set_element_handler($xmlParser, "startElement", "endElement"); 
    xml_set_character_data_handler ($xmlParser, "characterData"); 

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

    while ($data = fread($fp, 4096)) { 
     if (!xml_parse($xmlParser, $data, feof($fp))) { 
      die(sprintf("XML error: %s at line %d", 
         xml_error_string(xml_get_error_code($xmlParser)), 
         xml_get_current_line_number($xmlParser))); 
     } 
    } 

    xml_parser_free($xmlParser); 
    fclose($fh); 
?> 
+0

修正できないようなコードでエラーが発生しました。それは意味をなさない。私が得ているエラーは 'PHP Parse error:syntax error、unexpected error ';' /Users/irfanm/Desktop/mamp/xml2.php on line 12 'を参照してください。 –