2014-02-19 81 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);  
    } 
}