Dicas, tutorias, notícias sobre PHP, JS, jQuery, CSS, HTML, NodeJS, MySQL e muito mais
Converter Array para XML e Vice-Versa

Converter Array para XML e Vice-Versa

Fala galera!

hoje vou ensinar a vocês como converter seu array em um formato XML com o php.

lol
(Demostração do resultado da conversão da array para XML)

Primeiro de tudo vamos criar nossa array para poder trabalhar com ela no decorrer do post.

// Criando nossa array de teste
$frutas = array();

// Populando nossa array de teste
$frutas['cores'] = array('vermelha','amarela','laranja');
$frutas['vermelha'] = array('qtde' => 2, 'frutas' => array('nome' => 'Maça'));
$frutas['amarela'] = array('qtde' => 4, 'frutas' => array('Limão','Banana'));
$frutas['laranja'] = array('qtde' => 1, 'nome' => 'Mamão');

vocês podem visualizar a estrutura da array na imagem logo acima.

Ok, depois da array criada, vamos criar nosso objeto XML utilizando a classe SimpleXMLElement

# Criando um objeto XML com a classe SimpleXMLElement
$xml = new SimpleXMLElement('<frutas/>');

Feito isso já temos tudo para realizar a conversão, a logica se baseia em ler toda a array e inserindo os itens nesse objeto SimpleXML e no final chamando uma função dessa classe, ela mesmo converte o objeto simplexml em uma string XML.

Colocando a mão na massa!

A primeira coisa que devemos fazer é percorrer todas as posições da nossa array de frutas, para isso nada melhor que a função foreach

foreach($frutas as $chave => $item)
{
// Estamos percorrendo todas posições da nossa array!
}

Bom, dentro do nosso foreach vamos tratar isoladamente cada posição da array, na variável $chave vamos obter o nome da chave da posição da array, e na $item o conteúdo dessa posição..

estrutura_array
(
Demostração da estrutura de uma array em php)

olhando assim nos vem a ideia na cabeça..

Ahhh! matei a charada é simples, agora é fácil é só usar a função addChild (essa função cria um nó na estrutura do XML com o nome e o valor que você informar)  passando a variavel $chave como nome do nó e a variável $valor o conteúdo desse nó!

foreach($frutas as $chave => $item)
{
$xml->addChild($chave,$item);
}

Se vocês pensaram nisso, uma coisa: a vida não é tão fácil assim não! haha 😀

isso poderia ate funcionar em array simples, onde o conteúdo da posição é uma string simples, mas no nosso caso, em varias posições da array nosso conteúdo é outra array.. se nós fossemos implementar dessa forma acima, o php iria lançar o seguinte alerta

Warning: SimpleXMLElement::addChild() expects parameter 2 to be string, array given

Traduzindo: o segundo parâmetro da função addChild esperava uma string, mas foi informado uma array.

a função addChild aceita apenas uma string como conteúdo para cria o nó em XML. Então isso nos força a fazer o seguinte, sempre que o conteúdo for uma array, teremos que entrar nela percorrer o conteúdo até que encontramos uma string… uma solução para isso seria criar uma função recursiva.

Recursão (ciência da computação), um procedimento ou uma sub-rotina, implementado em uma linguagem de programação, cuja implementação referencia a si mesma
ou seja será uma função que ira chamar ela mesmo até que satisfaça uma condição para sair desse looping (muito cuidado ao criar funções assim, pois se você não definir uma “saída” para essa função ela pode rodar em looping infinito)

a saída da função recursiva que iremos criar será quando o valor encontrado na posição da array for uma string, ou seja sempre que o valor for uma array criamos um nó no XML com o nome da posição e invocaremos nossa função novamente para percorrer esse array e verificar o valor, se o valor for uma array ira chamar a função novamente com esse array como parâmetro… assim sucessivamente até o valor da posição da array ser uma string

então a função ficará dessa forma

function array_to_xml($array,&$xml)
{
foreach($array as $chave => $item)
{
if(is_array($item))
{
$subNo = $xml->addChild($chave);
array_to_xml($item, $subNo);

}
else
{
$xml->addChild($chave,$item);
}
}
}

OK!! com essa função irá resolver nosso problema de arrays bidimensionais , tridimensionais e por ai vai..

Observação:  usei ponteiro no 2 parâmetro da função que criamos, então basta apenas chamar a função que ela já irá aplicar as alterações direito em nosso objeto de XML, sem a necessidade de pegar o retorno da função e inserir no objeto

Então vamos trocar isso

foreach($frutas as $chave => $item)
{
$xml->addChild($chave,$item);
}

Por isso

array_to_xml($frutas,$xml);

// Imprimindo o XML na tela
echo $xml->asXML();

Bom se vocês forem tentar executar esse código com certeza o parse de XML do navegador irá retornar um erro.
Porque?

Se vocês analisarem a estrutura do XML gerado pela função asXML o nome dos nó em XML em determinados lugares ficaram números certo? e segundo o padrão de formatação do XML não pode iniciar com um número.. o problema esta no seguinte, em nossa array quando não definimos o nome da chave, automaticamente o php coloca o nome da chave como um numero que será auto incrementado de acordo com o uso de posições sem nome definido na chave..

se vocês perceberam em nossa array de frutas a posição cores é uma array onde cada valor lá não tem um nome na chave, então acaba saindo dessa forma

[0] => vermelha
[1] => amarela
[2] => laranja

Mas a solução para esse problema é bem simples basta apenas verificarmos o nome da chave antes de criar o nó, se for um numero, colocando uma string antes, seria como um prefixo de nome, a solução ficaria assim

function array_to_xml($array,&$xml)
{
foreach($array as $chave => $item)
{
if(is_array($item))
{
$prefixo = (is_numeric($chave)) ? 'item' : '';
$subNo = $xml->addChild($prefixo.$chave);
array_to_xml($item, $subNo);

}
else
{
$prefixo = (is_numeric($chave)) ? 'item' : '';
$xml->addChild($prefixo.$chave,$item);
}
}
}

E como um “passe de magica” nossa array foi convertida para XML! 😀

array_to_xml($frutas,$xml);
echo ($xml->asXML());

Resultado em XML

<frutas>
<cores>
<item0>vermelha</item0>
<item1>amarela</item1>
<item2>laranja</item2>
</cores>
<vermelha>
<qtde>2</qtde>
<frutas>
<nome>Maça</nome>
</frutas>
</vermelha>
<amarela>
<qtde>4</qtde>
<frutas>
<item0>Limão</item0>
<item1>Banana</item1>
</frutas>
</amarela>
<laranja>
<qtde>1</qtde>
<nome>Mamão</nome>
</laranja>
</frutas>

Bom é isso ai pessoal, esse foi um tutorial um pouco mais complexo, necessita de um pouco de conhecimento de função recursiva, mas não é um bicho de 7 cabeças né ? 😉

Para realizar a operação contraria é muito simples, basta apenas usar a função simplexml_load_file para abrir aquivos XML ou a simplexml_load_string para ler o XML de uma string

Exemplo

// Lendo o arquivo XML
$xml = simple_load_file ("caminho_do_arquivo.xml");

// Convertendo o Objeto SimpleXML para Array
$array = (array) $xml; // XML para Array

A operação inversa é muito mais fácil né?! hehe

Autor

fmansano

Desenvolver Web a mais de 5 anos, trabalha como freelancer, e analista de sistemas web, com experiências em varias linguagens de programação web, com o foco em PHP e Javascript/jQuery.

2 comments

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *