2014-02-19 2 views
2

Мне нужно разобрать 3 удаленных файла XML для моего магазина (продукты, цены, категории), самый большой из них - около 500 МБ +. Я должен разбирать их и вставлять в базу данных 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. Скачать и затем разобрать

сказать, что я хочу, чтобы разобрать products.xml внутри myxml.tar.gz, это даже возможно ?

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

это говорит о том, что файл пуст

+1

Если это одноразовый, используйте phpMyAdmin для импорта XML-файла для вас. – TonyWilk

+0

Я должен делать это каждые 2 часа. но спасибо! –

+1

Вы получите гораздо большую производительность, выбрав Batch Inserting to MySQL. Во-вторых, вы можете выполнить задание CRON, которое вызывает хранимую процедуру для загрузки файла .XML в месте, где MySQL Db запускается каждые два часа. – MackieeE

ответ

0

я сделать что-то, как вы.

У меня есть загрузка из zip-архива веб-сервиса с 3-мя большими сжатыми файлами. Я делаю это: на INIT я установил:

ini_set ('max_execution_time', 1000); // 600 секунд

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

ini_set ('default_socket_timeout', 1000);

загрузить файл почтового индекса в папку Temp:

/** 
    * 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-файлы из архива в папку Temp:

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 и я делаю запрос MySQL вставки с 1000 строк:

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);  
    } 
} 
Смежные вопросы