PHP将大XML文件拆分成更小的?

时间:2013-06-05 10:58:06

标签: php xml

hy,我希望你能帮助我! 我必须将较小的文件拆分为较小的数据以将数据放入db。 我读了很多帖子,我发现这是一个非常好的网址:

How can I split a big XML file into smallers with PHP?

但我有一些问题: 1.我必须阅读带有400.000记录的xml,脚本停在170.000,我真的不知道怎么样,我有什么改变吗? 2.是否有可能将数据放入? 3.我必须阅读一个巨大的文件和任何浏览器崩溃。你知道一些软件,我可以用简单的方式从url for mac读取数据吗?

非常感谢!

有关XML文件的更多信息:

我复制并通过xml格式;而不是三个点有信息。

<?XML version=“1.0” encoding=“UTF-8” ?> 

<vortigo> 

<annuncio> 

<id_annuncio> <![CDATA[ . . . ]]> </id_annuncio> 
<link> <![CDATA[ . . . ]]> </link> 
<titolo> <![CDATA[ . . . ]]> </titolo> 
<tipo_contratto> <![CDATA[ . . . ]]> </tipo_contratto> 
<tipologia> <![CDATA[ . . . ]]> </tipologia> 
<descrizione> <![CDATA[ . . . ]]> </descrizione> 

<classe_energetica> <![CDATA[ . . . ]]> </classe_energetica>
<indice_energetica> <![CDATA[ . . . ]]> </indice_energetica>
<numero_stanze> <![CDATA[ . . . ]]> </numero_stanze>
<numero_bagni> <![CDATA[ . . . ]]> </numero_bagni>
<superficie> <![CDATA[ . . . ]]> </superficie>
<stato_immobile> <![CDATA[ . . . ]]> </stato_immobile>
<prezzo> <![CDATA[ . . . ]]> </prezzo> 
<prezzo_giorno> <![CDATA[ . . . ]]> </prezzo_giorno>
<prezzo_settimana> <![CDATA[ . . . ]]> </prezzo_settimana>
<prezzo_scontato> <![CDATA[ . . . ]]> </prezzo_scontato>

<comune> <![CDATA[ . . . ]]> </comune> 
<nazione> <![CDATA[ . . . ]]> </nazione> 
<regione> <![CDATA[ . . . ]]> </regione> 
<provincia> <![CDATA[ . . . ]]> </provincia> 
<indirizzo> <![CDATA[ . . . ]]> </indirizzo> 
<cap> <![CDATA[ . . . ]]> </cap>
<zona> <![CDATA[ . . . ]]> </zona>
<longitudine> <![CDATA [ . . . ]]> </longitudine>
<latitudine> <![CDATA[ . . . ]]> </latitudine>
<data_aggiornamento> <![CDATA[ . . . ]]> </data_aggiornamento> 
<immagini>

<immagine>
<immagine_url> <![CDATA[ . . . ]]> </immagine_url>
<immagine_titolo> <![CDATA[ . . . ]]> </immagine_titolo>
</immagine>

<immagine>
<immagine_url> <![CDATA[ . . . ]]> </immagine_url>
<immagine_titolo> <![CDATA[ . . . ]]> </immagine_titolo>
</immagine>

...
</immagini> 

<tipo_venditore> <![CDATA[ . . . ]]> </tipo_venditore>
<agenzia_nome> <![CDATA[ . . . ]]> </agenzia_nome> 
<agenzia_comune> <![CDATA[ . . . ]]> </agenzia_comune> 
<agenzia_email> <![CDATA[ . . . ]]> </agenzia_email> 
<agenzia_url> <![CDATA[ . . . ]]> </agenzia_url> 

<piscina> <![CDATA[ . . . ]]> </piscina> 
<giardino> <![CDATA[ . . . ]]> </giardino> 
<condizionatore> <![CDATA[ . . . ]]> </condizionatore> 
<riscaldamento> <![CDATA[ . . . ]]> </riscaldamento> 
<balcone> <![CDATA[ . . . ]]> </balcone> 
<terrazzo> <![CDATA[ . . . ]]> </terrazzo> 
<ascensore> <![CDATA[ . . . ]]> </ascensore> 
<cucina> <![CDATA[ . . . ]]> </cucina> 
<arredato> <![CDATA[ . . . ]]> </arredato> 
<parcheggio> <![CDATA[ . . . ]]> </parcheggio> 

<portale> <![CDATA[ . . . ]]> </portale> 
<tipo_portale> <![CDATA[ . . . ]]> </tipo_portale> 
<logo_portale> <![CDATA[ . . . ]]> </logo_portale> 

</vortigo>

将信息输入到包含每个数据的所有列的数据库中。 先提前!!!!

2 个答案:

答案 0 :(得分:2)

您使用什么代码来解析XML?当你回答的问题得到解答时,你不应该使用easy SimpleXML,因为它非常慢并且内存密集。 下面是XMLReader-Class的一个简单示例,它对大文件非常有效,因为它流式传输它们而不是整个文件中的读取:

$xml = new XMLReader();
$xml->open('file.xml');

while ($xml->read()) {
    // elements only. skipp element end-tags and cdata etc
    if ($xml->nodeType == XMLReader::ELEMENT) {

          // process the Elements e.g. in a switch statement:
          switch ($xml->name) {
                //...
          }
    }
}

您可以在switch - 语句中应用更改,因为您可以通过$xml->readOuterXML()功能访问内容。如果您想要更轻松地访问内容,可能需要再次使用SimpleXMLElement解析特定部分:

 $elem = new SimpleXMLElement($xml->readOuterXML());

完成后不要忘记unset $elem,为即将开始的参赛作品释放内存。我使用完全相同的方法,并可以在2s内解析10k条目,具有相当大的内存使用率。

您的上一个问题:您可能希望将内容拆分为子部分。或者您可以下载文件,以便用户可以在他的计算机上将其作为一个整体打开。不幸的是,HTTP不是最快的协议,也不是为大规模文件设计的。

修改:我更新了我的gist on github以匹配您的示例数据。可能需要更多配置,例如因为你的<immagini>需要一些嵌套循环。但它会让你对如何解决这个问题有个很好的了解。

答案 1 :(得分:0)

您最有可能通过以下原因之一编写崩溃脚本: 1)PHP脚本的内存/时间限制。它可以在php.ini文件中设置 2)XML中的值不正确,您使用的解析器脚本无法解析这些值。