2012-04-11 85 views
1

我需要解析一個很大的XML。 100萬像素(甚至更多)。在PHP中解析BIG XML

例如: XML看起來是這樣的:

<notes> 
    <note> 
    <id>cdsds32da435-wufdhah</id> 
    <to>Tove</to> 
    <from>Jani</from> 
    <heading>Reminder</heading> 
    <body>Don't forget me this weekend!</body> 
    </note> 


x 1000000 different notes(or even more) 

</notes> 

每個音符都有聯合國唯一的ID。當我解析一個XML時,我需要首先查找是否在數據庫中存在特定ID的註釋,如果沒有插入它。

問題出在性能上(需要2個小時)。我嘗試從一個SELECT中取出數據庫中的所有ID(但也很大),所以我不會每次都詢問DB,並且我在PHP Array(Memory)中使用它們。

$sql = "SELECT id FROM 'notes'"; 
... 
$ids = Array with all ids 

我以前也分析與xml_parser的XML在一個循環:

while($data = fread($Xml, '512')) { 
    xml_parse($xmlParser, $data); 
} 

我認爲解析與simple_xml_parser一個XML可以產生太大變量PHP來處理它。

當我有一張紙條ID我檢查它是否存在於$ IDS比:

if (array_search($note->id, $ids) === FALSE) { 
    //than insert it 
} 

但它花費的時間太長。所以我發現PHP自帶了叫做Juddy Arrays http://php.net/manual/en/book.judy.php的特殊數組,但我不知道它們是否適合這個 - 我的意思是快速解析BIG數組。

我想也與Memcached,以存儲從許多變量DB的ID,但我想找到一個合適的解決方案。

在數據庫表中還有索引,以加快進程。 XML每週都在增長:)而且它每次都會記錄最後一次XML和新註釋的所有註釋。

問題? 如何在PHP中快速解析BIG ARRAYS?朱迪陣營是爲了這個嗎?將DB中的所有ids存儲在一個變量中是一個很好的解決方案? - 它可以在一次爲PHP大。

+0

只要你有足夠的內存空間,SimpleXML將會很好。如果您的數據庫查詢只是檢測XML中的重複ID,那麼使用SimpleXML意味着您根本不需要訪問數據庫。爲PHP配置足夠的內存':)' – halfer 2012-04-11 07:21:57

+0

你也可以使用一些簡單的文件操作將一個巨大的XML文檔分成幾個可管理的文檔。如果你的XML文件不斷增長,你將不得不在某一天做些什麼。每個月可能有一個XML文件? – halfer 2012-04-11 07:24:17

+1

不,xml_parse()正是你需要的,因爲它只是讀取緩衝區,然後你可以清理它。它看起來像爲查找創建了一個關聯數組,使用語言結構'isset()'來進行更快速的檢查,如'if(isset($ ids [$ note-> id]))'。我不確定這是否真的可以幫助你加快速度。也許你應該看看[SplFixedArray](http://php.net/splfixedarray)。 – 2012-04-11 07:28:00

回答

1

當我解析DMOZ database (2G xml)我已經使用Java解決方案(SAX解析器)。首先,我需要將XML(RDF格式)中的大量數據傳輸到MySQL數據庫中。我的PHP解決方案在6個小時內執行了此任務。但Java解決方案在15分鐘後完成了類似的任務。所以我可以告訴你:嘗試使用基於SAX解析器的Java解決方案。

+0

PHP有一個[SAX像XML解析器] (http://php.net/manual/book.xml.php),還有[基於libxml的XML讀取器](http://php.net/manual/book.xmlreader.php)。只是FYI。 – hakre 2012-05-31 10:26:29

1

您確定您需要在插入它之前查找數據庫中是否存在該項目?您可以告訴數據庫「如果它不存在,就插入它」:將唯一密鑰放在ID上,並使用INSERT IGNORE

+0

是的,我需要,因爲它會插入新的音符,並且還會在不同的表格中創建其他行,當音符是新的。 – Radek 2012-04-11 08:32:30