2011-07-08 11 views
2

私は2つの質問があります:xmlデータを効率的に解析するには?

1 - 私はXMLファイルを解析し、データをmysqlデータベースに挿入する必要があります。ファイルが約250 kB(ただし、さらに大きくなる可能性があります)で、サブノードが多いので、少なくとも3つのテーブルが必要です。私はSimpleXmlでxmlを解析し、すべてのデータをdbに挿入しました。しかし、この正確なファイルのために、それは私に多くのように見える約160秒かかりました。 短時間で、より良いやり方をする方法はありますか?

そして、別の質問は、あなたの答えを

おかげで...私はURLからXMLファイルを取得し、サーバに保存する必要がある、と私はこれを行う方法がわからないんだということです。

のURLからファイルを取得し、それを書くために、XML

function parse_xml($file=""){ 
    global $database; 
    if(file_exists($file) && !empty($file)){ 
     $sport = new SimpleXMLElement($file, null, true);  
     $count = count($sport->OddsObject)-1; 
     $listAttr = array(); 
     $start_time = time(); 
     for($i=0; $i <= $count; $i++){ 
      $countMatch = count($sport->OddsObject[$i]->Matches->Match)-1; 
      //echo $countMatch; 
      for($k=0; $k <= $countMatch; $k++){   
       $OOdata = $sport->OddsObject[$i]->children(); 
       $columns = array(); 
       $data = array(); 
       foreach($OOdata as $key => $value){    
        if($key != "Matches"){ 
         //$listAttr[$i][$key] = $attr; 
         $columns[] = $key; 
         if ($value != "") { 
          $data[] = "'" . $database->escape_value($value) . "'"; 
        } else { 
         $data[] = "NULL"; 
        } 
       } 
      }   

      //get matches: MatchId, Date, HomeTeam, AwayTeam 
      $Mdata = $sport->OddsObject[$i]->Matches->Match[$k]->children();  
      foreach ($Mdata as $key => $value) { 
       if($key != "OddsData"){  
        $columns[] = $key; 
        if ($value != "") { 
         $data[] = "'" . $database->escape_value($value) . "'"; 
        } else { 
         $data[] = "NULL"; 
        }  
       } 
      }      
      $cols = strtolower(implode(",",$columns)); 
      $values = implode(",",$data); 
      $sql = "INSERT INTO sports($cols) values(".$values.")"; 
      if($database->query($sql)) { 
       $last_id = $database->insert_id(); 

       $countData = count($sport->OddsObject[$i]->Matches->Match[$k]->OddsData)-1; 
       for($t=0; $t <= $countData; $t++){ 
        //get OddsData: Home-,Draw-, -Away ... 
        $ODdata = $sport->OddsObject[$i]->Matches->Match[$k]->OddsData[$t]->children(); 
        foreach($ODdata as $key=>$attr){ 
         $MID = $last_id; 
         $new_bet = Bet::make($attr->getName(),$attr, $MID); 
         $new_bet->save(); 

        }      
       } 
      } 
     } 
     $end_time = time() - $start_time; 
    }  
    return $end_time; 
} 
else{ 
    die("The file doesn't exist."); 
} 
} 
+0

データベースを更新する方法ではなく、ボトルネックがXMLパーサーであることを確認してください。トランザクションを使用していますか?あなたの解析コードの関連部分を表示できますか? 「URLからデータを取得する」には、もっと自分自身を検索してください。それは非常に一般的です。 – Mat

+0

私はどのように3つのテーブルが必要だと思っているのかわかりませんが、サンプルのXMLがあれば確かに役に立ちます。 – Sukumar

+0

@Mat - no Mat、ボトルネックがXMLパーサーであるかどうかわかりません...挿入が大丈夫であることを確認する必要がある場合、検証するレコードがたくさんあります。私は上のコードを追加します:) –

答えて

2

かなり簡単な方法を解析するためのコードは、のfile_get_contents()およびますfile_put_contents()です。

SimpleXMLは250kbのファイルでかなり効率的かつ高速でなければなりません。あなたの遅さはあなたのデータベースの挿入物にあるかもしれません。挿入物をデータベースにグループ化してみてください。私は、一度に50個のインサートを実行するのが最も効果的であることを発見しました(これは行のサイズにもよりますが)。おそらくプロセス全体をかなりスピードアップするでしょう。

+0

私はグループ化のアイデアを与えてくれてありがとう - 実際には、私は2つのチャンクで関数を分割しました。驚いたことに、それは160.Butの代わりにわずか30秒かかりましたが、私はXMLからXMLを読み込んで保存する方法についてはまだ分かりません。とりあえずありがとう。 –

1

は、私はあなたがSAXパーサに比べてメモリとCPUを大量に使用することができます

$dom = new DOMDocument(); 
... 
// read and insert into db 

DOMでそれを解析していると仮定し、データベースのコードをコメントアウトし、それはあまりにも使用するかどうかを確認するために、それを実行してみてください多くのCPUとRAMがある場合は、hereのように、SAXパーサーで再コーディングすることができます。

関連する問題