2014-02-19 46 views
2

我必須爲我的商店(產品,價格,類別)解析3個遠程XML文件,其中最大的文件大約爲500MB +。我必須解析它們並將其插入到mysql數據庫中。XMLReader錯誤

我可以從2種格式

  1. 所有3 XML文件名爲.tar.gz一個壓縮歸檔選擇
  2. 每一個單獨的,簡單的.xml

所以,基本上我有2個選項(我認爲)

  1. 解析XML「在旅途中」而流式傳輸
  2. 下載壓縮的XML然後解析它

我對兩者都有麻煩。

  1. 解析 「在路上」 的XML流傳輸的同時

    $url = "http://example.xml"; 
        $reader = new XMLReader(); 
        $reader->open($url); 
        $item = array(); 
        while ($reader->read()) { 
         switch ($reader->nodeType) { 
          case (XMLReader::ELEMENT): 
          if ($reader->localName == 'item') { 
           $item = array(); 
           $item['id'] = $reader->getAttribute('id'); 
           while ($reader->read()){ 
            if ($reader->nodeType == XMLReader::ELEMENT) { 
             $name = strtolower($reader->localName); 
             $reader->read(); 
             $item[$name] = $reader->value; 
            } 
            if ($reader->nodeType == XMLReader::END_ELEMENT && $reader->localName == 'item') 
             break; 
           } 
           // Yii framework's mysql query 
           Yii::app()->db->createCommand('INSERT INTO `products`    (id, name, parent_id, parent_name, brand, image) VALUES 
           ('.$item['id'].', "'.$item['name'].'", '.$item['parent_id'].', "'.$item['parent_name'].'", "'.$item['brand'].'", "'.$item['img'].'") 
           ')->execute(); 
    
        } 
    

    } }

此代碼工作正常與沒有mysql查詢,而是把各種錯誤,如果我把它們

分析器錯誤:在文檔

  1. 下載並結束額外的內容然後解析

說,我想分析裏面myxml.tar.gz products.xml,它甚至有可能?

$url = "compress.zlib:///myxml.tar.gz"; 
    $reader = new XMLReader(); 
    $reader->open($url); 
    $reader->read(); 

它說,該文件是空的

+1

如果這是一次性的,請使用phpMyAdmin爲您導入XML文件 – TonyWilk

+0

我必須每2小時大約做一次。但是謝謝! –

+1

您將通過批量插入到MySQL中獲得更多的性能。其次,你可以做一個CRON工作,它調用一個存儲過程來在MySQL Db的位置加載一個.XML文件,每兩個小時運行一次。 – MackieeE

回答

0

我做這樣的事情你。

我做的web服務zip壓縮包下載與壓縮3 XML大文件。 我這樣做: 上初始化我設置:

的ini_set( '的max_execution_time',1000); // 600秒

ini_set('mysql。connect_timeout',1000); // run large sql

ini_set('default_socket_timeout',1000);

我下載的zip文件到臨時文件夾:

/** 
    * Metoda care scrie arhiva pe hardisc 
    * @param $string textul de scris in fisierul zip 
    * @return string Calea catre fisiser 
    */ 
private function write_to_file($string) 
{ 

    $base = $this->tmpPath; 
    $date_folder = $base.date('Y_m').DIRECTORY_SEPARATOR.date('d'); 

    if(!file_exists($date_folder)) 
    { 
     mkdir($date_folder, 0777, TRUE); 
    } 

    $file = $date_folder.DIRECTORY_SEPARATOR.'products_'.date("Y_m_d_H_i").'.zip'; 

    // This uses less memory than file_put_contents 
    $f = fopen($file, 'w'); 
    fwrite($f, $string); 
    fclose($f); 

    return $file; 
} 

在此之後我從壓縮的XML文件解壓到臨時文件夾:

public function dezarhiveaza($file) 
{ 
    $zip = new ZipArchive; 
    $res = $zip->open($file); 
    if ($res === TRUE) { 
     $zip->extractTo($this->tmpPath); 
     $zip->close(); 
     $this->write_log('extract success'); 
    } else { 
     $this->write_log('error '); 
    } 
} 

而接下來我提取的列表來自XML的產品和我使用1000行插入MySQL查詢:

private function deserializeazaForme() 
{ 
    $formePath=$this->tmpPath. 
    "data".DIRECTORY_SEPARATOR.'forme.xml'; 
    $xml = simplexml_load_file($formePath);   
    $forme = $xml->xpath('//Table');   
    if($forme) 
    {   
     $strFormeInsertFirst="INSERT INTO `forme` (`id`, `denumire`) VALUES "; 
     $strFormeInsert=$strFormeInsertFirst; 
     foreach ($forme as $key=>$forma) { 
      $strFormeInsert .= "(".$forma->id.",'".$forma->denumire."),"; 
      if($key%1000==0 && $key >0){ 
       $strFormeInsert = rtrim($strFormeInsert, ",") ; 
       $strFormeInsert .=";"; 
       $this->runQuery($strFormeInsert); 
       $strFormeInsert=$strFormeInsertFirst; 
      } 
      } 
      $strFormeInsert = rtrim($strFormeInsert, ",") ; 
      $strFormeInsert .=";"; 
      $this->runQuery($strFormeInsert);  
    } 
}