2013-08-29 32 views
5

Aşağıdakileri yapmaya çalışıyorum ve yardıma ihtiyacım var:Akış ayrıştırması PHP'de 4 GB XML dosyası

Büyük bir XML dosyasını (4 GB) PHP ile ayrıştırmak istiyorum. Basit XML veya DOM kullanamıyorum çünkü tüm dosyayı belleğe yükledikleri için dosyayı aktarabilecek bir şeye ihtiyacım var.

Bunu PHP'de nasıl yapabilirim?

Yapmaya çalıştığım şey bir dizi <doc> öğesinde gezinmektir. Ve çocuklarından bazılarını yeni bir xml dosyasına yaz.

XML dosyası

böyle görünüyor ayrıştırmak çalışıyorum:

<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> 

G/almak <links> elemanı ve çocuklar hariç yeni bir XML dosyası içine her <doc> elementin tüm çocukları kopyalamak çalışıyorum .

<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> 

Ben büyük ölçüde akışı/dere ayrıştırma/akışı orijinal XML dosyası okuma ve daha sonra içeriklerinden bazıları yazılı olarak her türlü yardımı takdir ediyorum:

yüzden gibi yeni XML dosyası bakmak istiyorum PHP'de yeni bir XML dosyasına.

+3

Kontrol dışarı XMLReader sınıfı: http: //www.php.net/manual/en/intro.xmlreader.php Bu bir akış ayrıştırıcısıdır. Daha spesifik sorulara yardımcı olup olamayacağımı görmek için şu anda sorunuzu daha derinden okuyorum. – DeeDee

+0

@DeeDee XMLReader'ı duymuştum, ancak nasıl kullanılacağını bilmiyordum. Yardım için teşekkürler! –

+0

Elbette! Resmi belgelerde yapılan yorumların yetersizliğinden de anlaşıldığı üzere çok fazla kullanılmıyor. Ben çok uzun zamandır kullanmıyorum. Kodumun nasıl çalıştığını bana bildirir misin? Eğer hemen işe yaramıyorsa, işbirliği yapabilir ve neyin olduğunu anlayabiliriz. – DeeDee

cevap

4

İşte bir üniversite denemesi. Bu bir dosya kullanılıyor üstlenmez ve bir dosyaya yazmak istiyorsanız o: ​​Eğer belirtildiği gibi, bunun nedeni bellekte sığmaz,

<?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

Son düzenlemenizde ne vardı? Bu, mevcut sürüm ve daha önce okuduğum sürüm arasındaki farkı anlatamam. –

+0

Bu tam olarak aradığım şey gibi görünüyor, teşekkürler.Bu gece daha sonra deneyeceğim ve neler olduğunu anlatayım. –

+0

' DeeDee

0

bir DOM ayrıştırıcı kullanmak göze alamaz Bu senaryo için dosya boyutuna, ve eğer yapabilseydiniz bile, ilk önce tüm dosyayı yükledikçe yavaşlar ve bundan sonra yineleme yapmak zorunda kalırsınız, bu nedenle, bu durumda bir SAX ayrıştırıcısını (olay/akış yönelimli) denemeniz gerekir. , (doc,, url, abstract) öğelerini gizlediğiniz bu etiket için bir işleyici ekleyin ve her olay için yeni XML dosyasında bulunan düğüme ekleyin.

İşte What is the fastest XML parser in PHP?

bir ( test edilmemiş ) kodu ne olurdu numunesidir: Burada

daha fazla bilgiye sahip

<?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

Düzeltemediğim kodla ilgili bir hata alıyorum. Ayrıca mantıklı değil. Aldığım hata: 'PHP Ayrıştırma hatası: sözdizimi hatası, beklenmedik ';' /Users/irfanm/Desktop/mamp/xml2.php satır 12 'de. –