[英]How to use PHP to parse large XML file sequentially
我正在嘗試使用simpleXML在php中解析一個中等大小的XML文件(6mb)。 該腳本從XML文件中獲取每個記錄,檢查是否已將其導入,如果尚未導入,則將記錄中的更新/插入到我自己的數據庫中。
問題是我不斷收到關於超出內存分配的致命錯誤:
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 256 bytes) in /.../system/database/drivers/mysql/mysql_result.php on line 162
我通過使用以下行來增加最大內存分配來避免該錯誤(從此處開始提示):
ini_set('memory_limit', '-1');
但是,然后我以最大60秒的執行時間運行,無論出於何種原因,我的服務器(在Mac OS X上為XAMPP)都不允許我增加該時間(如果嘗試包含以下腳本,腳本將無法運行)像這樣的一行:
set_time_limit(240);
但是,這一切似乎都效率很低。 我是否應該能夠分解文件並按順序處理它? 在下面的控制器中,我有一個計數變量($ cycle)來跟蹤我正在進行的記錄,但是我無法弄清楚如何實現它,因為它仍然不必處理整個XML文件。
控制器(我正在使用CodeIgniter)具有以下基本結構:
$f = base_url().'data/data.xml';
if($data = file_get_contents($f))
{
$cycle = 0;
$xml = new SimpleXMLElement($data);
foreach($xml->person as $p)
{
//this makes a single call to db for single field based on id of record in XML file
if($this->_notImported('source',$p['id']))
{
//various process here, mainly breaking up the data for inserting into four different bales
}
$cycle++;
}
}
有什么想法嗎?
為了進一步了解我在做什么,我獲取了每個元素和子元素的大多數屬性,並將其插入到數據庫中。 例如,使用我的舊代碼,我有類似以下內容:
$insert = array('indiv_name' => $p['fullname'],
'indiv_first' => ($p['firstname']),
'indiv_last' => ($p['lastname']),
'indiv_middle' => ($p['middlename']),
'indiv_other' => ($p['namemod']),
'indiv_full_name' => $full_name,
'indiv_title' => ($p['title']),
'indiv_dob' => ($p['birthday']),
'indiv_gender' => ($p['gender']),
'indiv_religion' => ($p['religion']),
'indiv_url' => ($url)
);
有了使用XMLReader的建議(見下文),我如何完成對main元素和subelements的屬性的解析?
使用XMLReader 。
說您的文檔是這樣的:
<test>
<hello>world</hello>
<foo>bar</foo>
</test>
使用XMLReader:
$xml = new XMLReader;
$xml->open('doc.xml');
$xml->read();
while ($xml->read()) {
if ($xml->nodeType == XMLReader::ELEMENT) {
print $xml->name.': ';
} else if ($xml->nodeType == XMLReader::TEXT) {
print $xml->value.PHP_EOL;
}
}
輸出:
hello: world
foo: bar
令人高興的是,您還可以使用expand
將節點作為DOMNode對象獲取。
聽起來像是問題在於您在嘗試操縱整個xml文件之前將其讀入內存。 使用XMLReader逐步瀏覽文件流,而不是將所有內容都加載到內存中進行操作。
不使用xml,而是使用json呢? JSON格式的數據會小得多,因此我想您不會遇到相同的內存問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.