Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Pessoal,
Estou com uma dúvida, alguém sabe como incrementar arquivos XML grandes sem ter que carregar todo o arquivo na memória?
Estou trabalhando com arquivos XML que chegam a 300MB e de tempos em tempos preciso incrementar o final do arquivo com praticamente uma linha nova. Há alguma maneira de se fazer isso sem ter que carregar 300MB na memória apenas pra colocar uma linha nova?
Obrigado
>
php.net/fwrite
php.net/fseek
php.net/ftell
@braços e fique com Deus!
Com isso teria que usar fopen(), certo? Este não carrega todo o arquivo na memória?
Se não, não seria o mesmo que o código abaixo?
file_put_contents('arquivo.xml', '<tag>novo</tag>', FILE_APPEND);
não, fopen não abre o arquivo todo de uma vez.
na documentação mostra como ele faz.
por isso passei os três links, porque você vai precisar dos 3 ;-)
a maneira como você passou, vai fazer o append no final do ultimo node, ferrando o seu xml
@braços
exemplo
criar um arquivo de testes:
$file = 'teste.xml';
$fp = fopen($file,'w');
fwrite($fp, '<?xml version="1.0" encoding="UTF-8"?>');
fwrite($fp,'<dados>'.PHP_EOL);
for($i=0; $i<10; $i++){
fwrite($fp, '<node attr="teste" name="adfas" another="adfads"/>'.PHP_EOL);
}
fwrite($fp,'</dados>');
fclose($fp);
agora, testando a incrementação neste arquivo
$file = 'teste.xml';
$size = filesize($file);
$closeTag = '</dados>';
$newnode = '<newnode/>';
$fp = fopen($file,'r+');
$tmpCloseTag = '';
$currByte = $size;
// vamos procurar a tag de fechamento byte-a-byte
// isto porque poderia haver espaços em branco indesejaveis
// no meio do caminho
while($currByte > 0){
$currByte--;
fseek($fp, $currByte);
$tmpCloseTag = fgetc($fp) . $tmpCloseTag;
if(trim($tmpCloseTag) == $closeTag){
// achamos a tag de fechamento
break;
}
}
fseek($fp, $currByte);
fwrite($fp, $newnode . PHP_EOL . $closeTag);
fclose($fp);Olá, hufersil, desculpe a demora, tive problemas com o monitor.
Entendi, isso me ajudou muito!
Só mais uma pergunta, este método serve também para arquivos compactados em GZip, usando gzopen()? Se sim, como ficaria?
Abraço,
E muito obrigado.
Olá bom dia seguindo este exemplo estou adaptando para uma necessidade que tenho no momento e me deparei com um problema.
Preciso incrementar um dos nós, mas não estou tendo sucesso. Alguém poderia dar uma dica?
Meu XML está sendo gerado assim:
<orcamento>
<dados>
<modelo>Astra 2.0</modelo>
<ano>2013</ano>
<placa>DIL1973</placa>
</dados>
<produto>
<seq>0</seq>
<descricao>Amortecedor</descricao>
<quantidade>2</quantidade>
</produto>
<produto>
<seq>1</seq>
<descricao>Amortecedor</descricao>
<quantidade>2</quantidade>
</produto>
<produto>
<seq>2</seq>
<descricao>Amortecedor</descricao>
<quantidade>2</quantidade>
</produto>
</orcamento>
Onde coloquei o <seq></seq> o valor que tem nele, gostaria que saísse ao lado do produto ex:
<produto1></produto>
<produto2></produto>
....
Quando coloco a variável $i ali dá erro na geração do XML. Alguém poderia dar uma dica?
php.net/fwrite
php.net/fseek
php.net/ftell
@braços e fique com Deus!