2011-07-08 47 views
2

我有2個問題:如何有效地解析xml數據?

1 - 我需要解析XML文件並將數據插入到mysql數據庫中。假設文件大約爲250 kB(但可能更大),並且它有很多子節點,所以我至少需要3個表。我用SimpleXml解析了xml,併成功地將所有數據插入到了數據庫中。但是對於這個確切的文件,大約需要160秒左右。 有沒有一種方法可以在較短的時間內做得更好?

而另一個問題是,我需要從一個URL獲得XML文件並保存到服務器上,我不知道如何做到這一點...

謝謝您的回答。

解析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 - 沒有墊,我不知道瓶頸是XML解析器...有很多記錄來驗證,如果我必須確保插入是好的。我在頂部添加代碼:) –

回答

2

一個非常簡單的方法來從URL獲取文件和寫的代碼是file_get_contents()函數和file_put_contents()。

對於只有250kb的文件,SimpleXML應該是非常高效和快速的。你的緩慢可能與你的數據庫插入有關。嘗試將插入分組到數據庫。我發現每次運行50個插入通常效果最好(這取決於行大小)。這可能會加快整個過程。

+0

感謝給我分組的想法 - 事實上,我將這個功能分成了兩個塊,因爲這些ID是相同的,也是唯一的,並將所有內容寫入2個表格中。令人驚訝的是,它只花了30s而不是160.但我仍然不確定我是如何處理從url中讀取和保存xml的。不管怎樣,謝謝。 –

1

我假設你有

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

DOM可以使用相比,SAX解析器的內存和cpu一個顯著量解析它,你可以嘗試註釋掉數據庫代碼並運行它,看它是否使用過很多CPU和RAM,如果是這樣的話,你可能想用SAX解析器重新編碼它,如here