Browsing posts in: XML

Working with large XML files in PHP

There are many ways to manage big XML files in php. When I say large, is really large, 10, 20, 30 mebabytes. If we were open a file like this on a common server, we certainly will have a time-out error. This is because we usually use SimpleXML functions. This extensions is, in fact, a “Tree-based parser”, just like “DOM Parser”. They work great in small-medium XML files (~1MB). They put the whole content on memory, and then, parse it. But when we face a big content, the only option is the “Stream-based parsers”. These are more efficiently and faster, because it read the file on demand, and dont crush your servers memory.

Amongst the stream-based parsers, we have SAX and XMLReader. Ill show you how to read a big XML with XMLReader, because its easier and faster comparing to SAX, as you can se here.

The XMLReader is an extension enabled by default on PHP 5.1 and earlier. Born from XmlTextReader API (C#) and its based om libxml2 library. Before that, the XMLReader extension was only available on PECL. XMLReader supports namespaces and validations, including DTD and Relax NG (REgular LAnguage for XML Next Generation).

Well, lets to the code. Heres me XML example:

PHP code:

See, in determinate point I transform the actual block of data (the users tag) into a SimpleXML object, making the manipulation extremely easy. This way, you can easily work with big XML with no harm to the servers memory and no decrease on speed. My next move: try to optimize this script and maybe create a CodeIgniters library. That certainly will be a nice addon to developers, I think. Of course any help will be very welcome!

Did you like this? Share it:

Manipulando XML em grande escala com PHP

Existem vários métodos para manipular arquivos XML grandes. Quando digo grandes, são realmente grandes, 10, 20, 30 mega. Se fossemos abrir um arquivo desses em um servidor comum, certamente a operação ia terminar com um “time-out”. Isso porque geralmente usamos as funcoes da extensão SimpleXML. Esta extensão tem um “Tree-based parser”, assim como o “DOM Parser”. Funcionam perfeitamente em arquivos pequenos. Estes jogam o conteúdo do XML em memória, e dali você manipula. Mas quando os arquivos são muito grandes, o negócio é procurar um Stream-based Parser. São mais eficientes pois fazem a leitura do arquivo sob demanda, é mais rápido e não mastiga a memória do servidor.

Dentre os Stream-based Parsers, temos o SAX e o XMLReader. Vou demostrar como fazer a leitura de um XML utilizando o XMLReader, pois é mais fácil de implementar e de execução mais rápida, como podem acompanhar neste link.

O XMLReader é uma extensão habilitada e incluída por padrão a partir da versao 5.1 do PHP, surgiu através da derivação da API do XmlTextReader em C# e é baseada na biblioteca libxml2. Antes disso, a extensão XMLReader era disponível apenas na PECL. O XMLReader suporta namespaces e validações, incluindo DTD e Relax NG (REgular LAnguage for XML Next Generation)

Bom, vamos ao código. Meu XML de exemplo tem a seguinte estrutura:

[cc lang=”xml”]


João Da Silva
Avenida São Paulo
Centro
São Paulo
xx.xx-xx
(11) 1234-4321
12345678901
1234567890


.
.
.


[/cc]

Código em PHP:

[cc lang=”php”]
$vendedores = new XMLReader();
$vendedores->open(‘vendedores.xml’);
while ($vendedores->read()) {
switch ($vendedores->nodeType) {
case (XMLReader::ELEMENT):
if ($vendedores->localName == “vendedor”) {
$node = $vendedores->expand();
$dom = new DomDocument();
$n = $dom->importNode($node,true);
$dom->appendChild($n);
$simple_xml = simplexml_import_dom($n);
$codigo = $simple_xml[‘codigo’];
$nome = $simple_xml->nome;
$endereco = $simple_xml->endereco;
// Código customizado… insert, update, etc.
}
}
}
[/cc]

 

Percebam que em um determinado momento eu transformo o bloco de leitura atual, ou seja, a tag vendedores em um objeto SimpleXML, tornando a leitira extremamente fácil. Desta maneira voce pode tranquilamente trabalhar com arquivos XML de 5, 10, 50 mega sem detonar a memória do servidor. Meu próximo passo será melhorar essa rotina e transforma-la em uma library pro framework CodeIgniter. A quem possa interessar, toda ajuda é bem vinda!

Did you like this? Share it: