Como extrair dados de arquivo XML

O XML (eXtensible Markup Language) é uma recomendação da W3C (World Wide Web Consortium) para gerar linguagens de marcação para necessidades especiais. Esse formato tem várias vantagens, como representar as estruturas de dados relevantes da computação (listas, registros, árvores) e seu o próprio formato descreve a sua estrutura e nomes de campos, assim como valores válidos. Porém, o arquivo "XML simples" (veja exemplo a seguir) pode ser bem pouco intuitivo, dificultando sua edição direta com editores ASCII no caso de muitos dados - a grande quantidade de informação repetida também acaba prejudicando a velocidade de transferência real de informação.

<?xml version="1.0" encoding="UTF-8" ?>
<main>
	<informacao>Valores</informacao>
	<NumeroDeValores>2</NumeroDeValores>
	<variavel>
		<data>2015-02-01</data>
		<lugar>SaoPaulo</lugar>
		<valor>123</valor>
	</variavel>
	<variavel>
		<data>2015-02-02</data>
		<lugar>SaoPaulo</lugar>
		<valor>456</valor>
	</variavel>
</main>

Assim, segue um script em PHP para ajudar a extarir os dados contidos no exemplo acima e gravá-los em um arquivo CSV; além disso, ele calcula a média dos valores e imprime o resultado na tela. Os campos devem ser personalizados de acordo com os dados contidos no arquivo XML, mas já serve de início. Nesse script, deve-se incluir dois argumentos ao iniciar para servirem de nome ao arquivo final, mas podem ser usados em outras partes do código.

Para rodar em seu computador, deve-se primeiro instalar o PHP através do comando "sudo apt-get install php5" e executar o script a seguir usando o comando "php NomeDoScript.php ValorDeEntrada1 ValorDeEntrada2".

#!/usr/bin/php
<?php

$AnoMes = $argv[1];
$Cidade = $argv[2];
$xml_file = simplexml_load_file(dirname(__FILE__).'/arquivo_de_dados.xml');
// Caso o arquivo esteja em uma url, usar as seguintes linhas
//$url = "http://www.site.com.br/path";
//$xml = simplexml_load_file($url);
$total = 0.0;
print("Valor medio para o mes de ".$AnoMes." para a cidade ".$Cidade).chr(10);

for($j=0;$j<$xml_file->NumeroDeValores;$j++){
    
    $Data = $xml_file->variavel[$j]->data;
    $Lugar = $xml_file->variavel[$j]->lugar;
    $Valor = $xml_file->variavel[$j]->valor;
    
    // Cabeçalho - 1a linha do arquivo CSV
    $saida = "data,lugar,valor".chr(10);
    // Linhas seguintes
	$saida .= $xml_file->variavel[$j]->data.",".$xml_file->variavel[$j]->lugar.",".$xml_file->variavel[$j]->valor.chr(10);
	$total = (float) $total + (float) $valor;

	// Gravar o arquivo CSV
	$handle = fopen(dirname(__FILE__)."/".$Cidade."-".$AnoMes.".csv", "w");
	fwrite($handle,$saida);
	fclose($handle);
}
$media = (float) $total/$xml_file->NumeroDeValores;
print("MEDIA -> ".$media).chr(10);

?>

Algumas observações. O comando "dirname(__FILE__)" retorna o diretório presente do sript. O comando "$xml_file->variavel[$j]->data" vai no arquivo definido na variável "$xml_file", busca o campo da tag "variavel" na posição "$j" e lá dentro pega uma "subtag" chamada "data". O caractere "chr(10)" indica quebra de linha. O parâmetro "(float)" serve para forçar o PHP a entender o conteúdo da variável como um valor de ponto flutuante.

Outra opção é utilizar a linguagem R. Para isso, instale o pacote XML através do seguinte comando no terminal R (onde lib é o endereço dos pacotes instalados):

install.packages("XML", lib="~/Rpacks")

Talvez seja necessário a instalação de algum módulo no Linux ("sudo apt-get install libxml2-dev", por exemplo). Depois, basta seguir o exemplo abaixo:

require(XML,lib=end_libs)
filename = paste(diretorio,'/lugares.xml', sep='')
temp = xmlToDataFrame(filename)
lugares = temp$nome
for (n in lugares){
	lugar=n
	print(lugar)
}

A função "xmlToDataFrame" extrai uma tabela dos valores disponíveis no arquivo utilizado como argumento.

Por fim, existe também o seguinte comando em shell script, cujo exemplo segue abaixo:

lugares=($(cat $DIR/lugares.xml | grep -oP '(?<=nome>)[^<]+'))
for lugar in "${lugares[@]}"; do
	echo "Cidade: " $lugar
done

O comando grep lê o que estiver dentro da tag "nome".

Compartilhe o link desse texto, mas se for copiar algum trecho, cite a fonte. Valorize nosso trabalho.
Mais informações na licença de uso do site.

Um Pingback/Trackback