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:

14 Comments

  • lucia |

    Prezado Vicente,

    Tentei executar o codigo acima de deu o seguinte erro:
    Notice: Undefined variable: reader in C:\Program Files\Apache Software Foundation\Apache2.2\htdocs….. on line 9.

    Ou seja está dando erro na linha 9 com relação $reader->explode.

    A versão do meu php é 5.2

    Qual será a razão?

    Muito grata Lucia

  • Vicente Russo Neto |

    Olá Lucia,

    Acredito que houve um equívoco no seu comentario, pois nao existe o métido “explode”, e sim “expand”. Caso o erro seja mesmo no expand, verifique se há instalado no servidor a extensão XMLReader e SimpleXML.

    Embora o erro seja no XMLReader, não imagino que seja um erro de falta de extensão, pois daria erro ao tentar instanciar um novo XMLReader. Poderia postar seu código?

  • Lucia Terra |

    Olá vicente,

    Aquele comentario sobre o expand já foi resolvido. Meu dico PHP está funcionando bem. os arquivos xml que tenho trabalhado são da ordem de 26mega. Por exemplo leio o arquivo e gero um gráfico. Em algumas situações chego a ler 6 arquivos um de cada vez, para então gerar o gráfico. Percebo que o processo fica um pouco demorado, mas funciona. Pelo que entendi do seu post a forma mais rápida e eficiente de ler grandes arquivos é o XML reader. Existe alguma forma de fortná-lo mais rápido?

  • Vicente Russo Neto |

    Olá Lucia

    Até onde eu sei, o XMLReader é de fato o mais rápido. Vale lembrar que um arquivo de 26 mega, por mais rapido que o método seja, sempre vai levar muito mais tempo do que um arquivo com a metade do tamanho, por exemplo…

  • Paulo C Faccioli |

    Lembrando que algumas manipulações de large files em PHP precisam de uma configuração diferenciada no php.ini. Ex para carregar arquivos de 100Mb:

    ; Maximum size of POST data that PHP will accept.
    post_max_size = 100M

    ; Maximum allowed size for uploaded files.
    upload_max_filesize = 100M

  • Filippe Brito |

    O problema do “expand” nesse exemplo é simples, a variável “$reader” não existe, era pra ser usada no seu lugar “$vendedores” pois essa variável é quem está recebendo a instância do construtor “XMLReader”. Ao trocar aqui no meu pc funcionou.

    Vicente, muito bom o tutorial, peço para efetuar essa correção para futuras consultas.

  • Antonio |

    Bom Dia amigos estou com um problemão, dos Grandes Tamanho do problema é 114.673 Mega
    Isso aí mais de 14 Gb de Xml teria alguma ideia para Extrair essas Informações dele.
    Cara eu até Pago por esta Informação

    Des de ja Agradeço.

    Obs: é um arquivo unico (1 de 14GB)

  • Vicente Russo Neto |

    Olá Antonio. Imagino que esta solução do post funcione pra você, DESDE QUE o servidor tenha memória RAM suficiente pra aguentar os 14GB. Chegou a testar o código?

  • Brambilla |

    Bom dia, bem legal essa dica, meu o arquivo XML que estou tentando importar é de 15 a 30MB, e deu certo, mais quando vai para coloco os Mysql consulta, updates e inserts ele da o seguinte erro

    Error Summary
    HTTP Error 500.0 – Internal Server Error
    c:\php\php-cgi.exe – The FastCGI process exceeded configured request timeout

    o que seria esta problema? o servidor é Windows

    att.
    Brambilla

  • Brambilla |

    Bom dia, bem legal essa dica, meu o arquivo XML que estou tentando importar é de 15 a 30MB, e deu certo, mais quando vai para coloco os Mysql consulta, updates e inserts ele da o seguinte erro

    Error Summary
    HTTP Error 500.0 – Internal Server Error
    c:\php\php-cgi.exe – The FastCGI process exceeded configured request timeout

    o que seria esta problema? o servidor é Windows

    att.
    Brambilla

  • effendy |

    Our goal at vape4style.com is to give our consumers along with the very best vaping experience possible, helping them vape with style!. Located in New York City and in service considering that 2015, our experts are a custom-made vaping superstore offering all forms of vape mods, e-liquids, pure nicotine sodiums, capsule units, containers, rolls, and other vaping accessories, like electric batteries and also outside wall chargers. Our e-juices are always clean due to the fact that our experts certainly not only offer our items retail, yet additionally distribute to local NYC stores along with give wholesale possibilities. This allows us to constantly rotate our inventory, offering our consumers and shops with the most freshest inventory feasible.

    If you are actually a vaper or attempting to get off smoke cigarettes, you are in the best location. Want to conserve some cash present? Rush and join our email mailing list to obtain special nightclub VIP, vape4style discounts, promos as well as totally free giveaways!

    We are actually an unique Northeast Yihi distributor. Our team are actually also authorized reps of Bad Drip, Harbour Vape, Charlie’s Chalk Dirt, Beard Vape, SVRF through Saveur Vape, Ripe Vapes, Smok, Segeli, Shed Vape, Kangertech, Triton and a lot more. Do not view one thing you are actually trying to find on our internet site? Certainly not a problem! Only permit us understand what you are trying to find and also our experts will certainly find it for you at a discounted rate. Possess a question regarding a certain item? Our vape specialists will certainly rejoice to deliver more information concerning everything our team sell. Just send our company your inquiry or phone our company. Our staff will be glad to help!

    derailed e-liquid shop – Hakutaku atomizer

  • Sprineffendy |

    House maid agency Bronx : house maid cleaning services

    Trained specialists specialized company Bellerose can hold spring cleaning 2018.

    We hold spring cleaning plot in areas , we can put in order your grounds garden , apartment, tanhaus.

    Our Limited liability Limited Partnership cleaning production company Midwood JUSTINE, is engaged spring cleaning cottages in Silver Lake under the direction of JACKIE.

    Cleaning work in the spring is a good case implement cleaning the house, private households and offices, apartments.
    Streets, courtyards, gardens, squares and urban territories very important not only clean up from dirt accumulated in snow Cleaning in the spring is an opportunity do a huge mass of work on tidying up urban areas, rooms and also in my apartment.
    Roads, courtyards, parks, squares and other urban areas need not only clean up from dirt accumulated in snow, take out the garbage, but also prepare for the summer period. For this should be restored damaged sidewalks and curbs, fix broken architectural small forms sculptures, flowerpots,artificial reservoirs,benches, fences, and so on, refresh fences, painting and many other things.
    Our Limited Partnership holding carries out spring cleaning in the district, but with pleasure we will certainly help tidy up .
    Our good specialists Indian Village do spring cleaning 2018.

So, what do you think ?