XMLReader错误

时间:2014-02-19 15:37:44

标签: php mysql xml parsing xmlreader

我必须为我的商店(产品,价格,类别)解析3个远程XML文件,其中最大的约为500MB +。我必须解析它们并插入到mysql数据库中。

我可以选择2种格式

  1. 压缩在一个.tar.gz存档中的所有3个XML文件
  2. 每个单独的,简单的.xml
  3. 所以,基本上我有2个选项(我认为)

    1. 在流式传输时“随时随地”解析XML
    2. 下载压缩的XML然后解析它
    3. 我两个都有麻烦。

      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();
        
            }
        

        } }

      2. 这段代码可以正常使用没有mysql查询,但是如果我把它们放在一起会抛出各种错误

          

        解析器错误:文档末尾的额外内容

        1. 下载然后解析
        2. 说我想在myxml.tar.gz中解析products.xml,它甚至可能吗?

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

          它说文件是空的

1 个答案:

答案 0 :(得分:0)

我喜欢你。

我已经从web-service zip archive下载了压缩的3 xml大文件。 我这样做: 在init i上设置:

  

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

     

ini_set('mysql.connect_timeout',1000); //运行大型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;
}

在此之后,我将zip文件从zip文件夹中提取出来:

    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);       
    }   
}