在PHP中解析BIG XML

问题描述:

我需要解析一个很大的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

当我解析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

您确定您需要在插入它之前查找数据库中是否存在该项目?您可以告诉数据库“如果它不存在,就插入它”:将唯一密钥放在ID上,并使用INSERT IGNORE

+0

是的,我需要,因为它会插入新的音符,并且还会在不同的表格中创建其他行,当音符是新的。 – Radek 2012-04-11 08:32:30