Gerar XML com PHP

  • Autor do post:
  • Categoria do post:PHP DEV

Gerando XML com PHP5

Vamos ver como gerar  um arquivo XML simples usando PHP5 e API DOM, se você não possui o PHP5 baixe o EasyPHP.


<?php
#versao do encoding xml
$dom = new DOMDocument("1.0", "ISO-8859-1");

#retirar os espacos em branco
$dom->preserveWhiteSpace = false;

#gerar o codigo
$dom->formatOutput = true;

#criando o nó principal (root)
$root = $dom->createElement("agenda");

#nó filho (contato)
$contato = $dom->createElement("contato");

#setanto nomes e atributos dos elementos xml (nós)
$nome = $dom->createElement("nome", "Rafael Clares");
$telefone = $dom->createElement("telefone", "(11) 5500-0055");
$endereco = $dom->createElement("endereco", "Av. longa n 1");

#adiciona os nós (informacaoes do contato) em contato
$contato->appendChild($nome);
$contato->appendChild($telefone);
$contato->appendChild($endereco);

#adiciona o nó contato em (root) agenda
$root->appendChild($contato);
$dom->appendChild($root);

# Para salvar o arquivo, descomente a linha
//$dom->save("contatos.xml");

#cabeçalho da página
header("Content-Type: text/xml");
# imprime o xml na tela
print $dom->saveXML();
?>

 

Neste exemplo utilizamos dados pré-definidos, mas poderiamos ter utilizado o resultado de uma consulta SQL.

Exemplo funcionando Exemplo XML

Agora, o resultado é excelente, porém, repetir esses comandos acima para cada contato é bem desgastante, vejamos uma função para automatizar a criação dos contatos.

<?php
function addContato($document, $nome, $fone, $end)
{
 #criar contato
 $contato = $document->createElement("contato");

 #criar nó nome
 $nomeElm = $document->createElement("nome", $nome);

 #fone
 $foneElm = $document->createElement("telefone", $fone);

 #endereco
 $endElm = $document->createElement("endereco", $end);

 $contato->appendChild($nomeElm);
 $contato->appendChild($foneElm);
 $contato->appendChild($endElm);
 return $contato;
}

$dom = new DOMDocument("1.0", "ISO-8859-1");
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;

$root = $dom->createElement("agenda");

#utilizando a funcao para criar contatos
$Tiao = addContato($dom, "Tiao J.", "5555-4444", "R. Jaú, 3");
$Joao = addContato($dom, "Joao S.", "4444-5555", "R. Itú, 4");

#adicionando no root
$root->appendChild($Tiao);
$root->appendChild($Joao);
$dom->appendChild($root);

#salvando o arquivo
$dom->save("agenda.xml");

#mostrar dados na tela
header("Content-Type: text/xml");
print $dom->saveXML();

?>

A função acima produz o mesmo resultado que o primeiro exemplo, porém de uma forma mais simples na hora de criar os contatos, sendo assim para utilizar em seus estudos aconselho utilizar a função do segundo exemplo.

Exemplo funcionando Exemplo XML utilizando a função

Leia o outro post sobre gerar XML com PHP em :
http://clares.com.br/2009/09/29/gerar-xml-com-php5-e-xmlwriter/

Este outro post é ainda mais simples de entender.

Até a próxima,

Rafael Clares

Este post tem 65 comentários

  1. Michel

    Cara, como seria para LER um arquivo XML ?

  2. Laerti Borba

    Cara, muito bom este seu exemplo, me ajudou muito, pois tinha uma prova onde deveria criar um formulario em PHP e ele submeter os dados para um arquivo XML, e foi com esta sua dica que me salvou. Valeu.
    Laerti

  3. Ivaldo Trentin

    Kra, muito lega a maneira que usou para explicar a maioria dos lugares usa a criação de arquivos xml da mesma maneira que criamos os txt, somente concatenando string… dessa maneira fica muito mais simples e claro o codigo.

  4. Glauber

    Show de bola!!
    Parabéns!!

  5. Gabriel Lau

    Rafael, tem como tu dar um exemplo de como seria usando um banco de dados???
    Tipo: Sempre que eu inserir um registro novo no banco, ele pega os dados que já tem lah, e atualiza essa lista no xml…

    Está show de bola essa sua solução para gerar XML… já está no meu BLOG.. 😉

    1. Rafael Clares

      Gabriel, beleza ai…então tá!
      Cara, para fazer com BD basta você trocar as linhas onde os dados são inseridos manualmente, mas isso é bem óbvil, ok, vamos lá…
      coloque as linhas abaixo dentro do seu laço que está retornando os dados do BD, agora se você quer aprender à utilizar um BD é outra coisa… infelizmente não é o propósito do Post.
      Supondo que você utiliza Postgre e ja chamou a conexao com o banco:
      //conexao ok
      $strQuery = “select * from clientes”;
      $query = pg_query($strQuery);
      while ($row = pg_fetch_array($query))
      {
      $nome = $row[‘nome’];
      $telefone = $row[‘telefone’];
      $endereco = $row[‘endereco’];
      $nome = $dom->createElement(”nome”, “$nome”);
      $telefone = $dom->createElement(”telefone”, “$telefone″);
      $endereco = $dom->createElement(”endereco”, “$endereco″);
      $contato->appendChild($nome);
      $contato->appendChild($telefone);
      $contato->appendChild($endereco);
      $root->appendChild($contato);
      }

      Seria algo do tipo acima… num post futuro farei isso.

  6. Alexandre

    Olá Rafael,
    Excelente trabalho, mas precisava de um help seu!

    Utilizei essa função em um projeto recente, porém ao obter do bd dados acentuados ocorre o seguinte warning:
    —————————————-
    Erro no processamento de XML: caracteres inúteis após um elemento do documento
    Posição: xml_fichas_export.php
    Número da linha 2, coluna 1:Warning: DOMDocument::save() [function.DOMDocument-save]: output conversion failed due to conv error, bytes 0xC3 0x4F 0x20 0x50 in X:moweswwwxml_fichas_export.php on line 192
    ^
    —————————————-

    A linha em questão é sempre exatamente onde está a palavra acentuada. Troquei o padrão para UTF-8 e deu certo, porém o cliente ao importar exige que seja utilizado ISO-8859-1:

    $dom = new DOMDocument(“1.0”, “UTF-8”);
    $dom = new DOMDocument(“1.0”, “ISO-8859-1”);

    Saberia me dizer uma solução para o problema?

    Obrigado!

    1. Rafael Clares

      Alexandre,
      já tentou usar o utf8_decode($var) nas palavras/strings/vars com acentos ?
      De toda forma, o caminho é por aí ! Utilize encode/decode das strings/vars que compõe o XML!
      abraços,

  7. Bruno

    Prezado Clares…

    Eu gostaria de aprender inserir um nodo antes (ou depois) de algum outro nodo específico no arquivo xml já existente.

    Tem como me ajudar nessa?

  8. Cadu

    Muito boa a dica! Simples e eficiente!

    Parabéns!

  9. Jose Ricardo

    Saudações…
    Interessante esse exemplo, gostei muito mas estou com um pequeno problema…
    minha aplicação é assim:

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $urlapf);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $Resposta = curl_exec($ch);
    curl_close($ch);

    Depois disso, faço o tratamento necessário, separo as devidas informações em variáveis e vizualizo na tela.
    Funcionando tudo blz…
    Quando vou gerar o xml ele não está puxando os valores

    $dado1 = $dom->createElement(“dado1”, “$Dado01”);
    $dado2 = $dom->createElement(“dado2”, “$Dado02”);
    $dados_principais->appendChild($dado1);
    $dados_principais->appendChild($dado2);

    O que pode estar acontecendo?????

  10. Alcir

    como faco para inserir atributos com api DOM

  11. fernando

    bom material amigo

  12. Neto

    Olá,ótimo artigo!
    exatamente o que procurava.

    Abraços.

  13. Diogo

    Oi Rafael, consegui utilizar teu código perfeitamente, está lista até do banco de dados.

    Mas tenho uma dúvida, como faço para apenas exibir as informações e não salvar??

    Abraço.

    1. Rafael Clares

      Diogo, basta comentar a linha abaixo:
      $dom->save(“contatos.xml”)

      abraços

  14. Carlos Correa

    Excelente, não conhecia essa API, muito prática para criação de conteúdo. Irei utiliza-la para a integração do meu sistema com NFe.
    Valeu pela dica.

    Abraços

  15. Tamar

    cara como o wordpress cria o arquivo xml para feeed(rss), pois não esta mostrando as imagens dos meus post, deve estar faltando alguma linha de código.. grato (papertoyart.com)

    1. Rafael Clares

      cara, eu não sei como o wordpress cria os arquivos para feeds!
      Mas se quiser ver como criar feeds, dê uma busca no blog, tem um exemplo básico!

  16. Giancarlo

    desculpa ressussitar aki, mas eu to querendo adicionar uma coisa do tipo mas estou com umas dificuldades…se puder ajudar nesse sentido…vlws ae

    1. Rafael Clares

      Giancarlo, rs rs nossa cara você pode perguntar à vontade mas confesso que não entendi muito o que quis dizer.
      Bem, me fale o que são as “coisas do tipo” e depois o “sentido” para eu poder tentar ajuda-lo ok, me fale da dificuldade.
      um abraço

  17. dyegoreisa

    Muito prático.
    Me ajudou muito!

  18. Samuel

    Olá, gostei muito deste POST, e aproveitei para mandar um comentário, acessem o site: http://syslep.wordpress.com/, para ver alguns POST de Criação de LOGI com um PACKAGE nos mesmo criamos.

  19. valmir santos

    o legal, muito bom esse post, foi de muito ajuda, obrigado.

  20. panetony

    Rafael,

    seu artigo me ajudou bastante… valeu!

    estou com uma dúvida, e gostaria de saber se você pode me ajudar… é o seguinte… se eu coloco no xml o caracter especial & é salvo como &

    ok… é isso que gostaria que fizesse mesmo…

    porem qdo coloco ” o xml salva como ” e gostaria que salvasse como "

    será que poderia me ajudar com isso ?!

    valeu !

    abraço

    1. Rafael Clares

      Rapaz, não entendi muito bem não … você coloca um caracter e quer que apareça outro, é isso?

  21. Matheus

    Poxa sou novo aqui mas cheguei pra ficar, esse blog é animal mano… muitas dúvidas que eu tinha estão aqui solucionadas, até mesmo uma coisa que eu precisei fazer e com muito custo você explicou aqui perfeitamente e bem fácil.

    Parabéns, continue assim eu gostaria de aproveitar e deixar um pedido…

    POR FAVOR, FAÇA MAIS AULAS DE XML COM PHP POR FAVOR…..

    Valeu

    1. Rafael Clares

      Valeu Matheus, pode deixar vou escrever sim, é que esse mês tem sido muito corrido. abs

  22. Raphael

    Ele quer saber se deve colocar & ou & para exibir o “&”
    No caso, o correto seria & creio eu.

  23. Erick Menezes

    Boa Eu nao to conseguindo salvar ele exibe no firefox e no Ie normal mas nao salva no servidor
    to rodando IIS 5.1 aki tem que configurar permição de pasta para gravar ? ja tentei de varias formas mas nada
    OBS: as duas ultimas linhas eu ja tentei das duas formas com echo e sem mas nada

    createElement(“enviar”);
    $tipoElm = $document->createElement(“tipo”, $tipo);
    $nomeElm = $document->createElement(“nome”, $nome);
    $endElm = $document->createElement(“endereco”, $end);
    $cmdElm = $document->createElement(“cmd”, $cmd);
    $contato->appendChild($tipoElm );
    $contato->appendChild($nomeElm);
    $contato->appendChild($endElm);
    $contato->appendChild($cmdElm);
    return $contato;
    }
    $dom = new DOMDocument(“1.0”, “ISO-8859-1”);
    $dom->preserveWhiteSpace = false;
    $dom->formatOutput = true;
    $root = $dom->createElement(“comando”);
    $escrever = addContato($dom, “Tipo0”, “MRmenezes”, “0”, “TELNET”);
    $root->appendChild($escrever);
    $dom->appendChild($root);
    header(“Content-Type: text/xml”);
    print $dom->saveXML();
    echo $dom->save(“cmd.xml”);
    $dom->save(“agenda.xml”);
    ?>

    1. Rafael Clares

      Erick, no IIS 5 não sei te dizer ao certo cara mas tente passar o caminho absoluto de onde quer salver para fazer um teste. ex: $dom->save(“c:\temp\agenda.xml”);
      De toda forma tente me passar alguma mensagem de erro se houver alguma sendo exibida!

  24. Tiago Sutil

    Não to conseguindo salvar o arquivo ele da esse erro de permissão negada, por fazvor se conseguir me ajudar eu agradesso. Ja tentei colocar o caminho por extenso, tentei com

    $dom -> save ( $_SERVER [ ‘DOCUMENT_ROOT’ ]. ‘eventos.xml’ );

    o erro é sempre o mesmo

    Warning: DOMDocument::save(/dados/www/dominios/htdocs/nosite/www.nosite/eventos.xml) [function.DOMDocument-save]: failed to open stream: Permission denied in /dados/www/dominios/htdocs/nosite/www.nosite/geraxmleventos.php on line 53

    1. Rafael Clares

      Tiago, permissão você dá na pasta onde está tentando salvar… tem que dar permissão de gravação, se estiver hospedado em algum local, você muda a permissão pelo FTP, alterando para 0776 a permissão da pasta.

      1. Tiago Sutil

        Eu consegui dando a permissão 777. Vlw otimo post.

        Fujindo do proposto gostaria de trocar ideias uma hora dessas entre a troca de informação entre flash (via java script) chamando em uma paginas em php ou html… Depois de muito fazer ainda bato a cabeça com o IE, tipo ele so funciona com o modo de compatibilidade ativado.

        Bom vlw. Abrass

  25. Samuel

    Olá, imagine que o meu XML é o seguinte:

    musicas/GATA.mp3
    Gata de Junho
    InovaSamba

    Se eu seguir a risca o exemplo acima, funciona, porem ele replica o nó que seria o meu principal, . Como faço para apenar replicar do nó para frente?

    1. Rafael Clares

      Precisaria ver o seu código PHP para entender o que há!

  26. Jean Carlos

    Olá! Estou tentando fazer da seguinte forma!

    Estou com um formulario de cadastro. Gostaria que ele enviasse os dados para outro php, esse transformava os dados em xml. até aqui tudo bem, mas ao invés de salvar ele no pc, pegasse o $dom e enviasse como anexo por email.

    Poderia me ajudar?

    1. Rafael Clares

      Jean, cara não entendi muito bem. Enviar o dom em anexo? Rapaz, nunca vi isso não, não seria o caso de enviar o XML por email?

      1. Jean Carlos

        Isso, eu gostaria de enviar o XML como anexo sem precisar salvar ele localmente no servidor

        1. Rafael Clares

          Jean, não tem como anexar algo que não existe fisicamente, o que faço é o seguinte:
          1 – crio o arquivo no disco
          2 – anexo e envio por email
          3 – apago o arquivo do disco

          Leia o post sobre o PHPMailler, nele tem uma função simples para anexar arquivos, daí ficaria algo assim:

          $dom->save(“contatos.xml”); //grava no disco
          $mail->AddAttachment(“contatos.xml”); // esse método é do phpmailer para anexar arquivos
          $mail->send();
          @unlink(“contatos.xml”); //remove o arquivo do servidor

  27. Mel Oliveira

    Eu postei um problema aqui, mas nao acho mais, foi apagado?

    1. Rafael Clares

      MEl, não foi apagado, o problema é que os comentários devem ser aprovados para aparecer e ainda não aprovei, na verdade é que não aparece nada. Você postou códigos na caixa de comentários e quando faz isso
      ele não aparece. O ideal é você colocar o código no pastebin.com e postar aqui o link do seu código. Assim poderei tentar ajudar.

  28. Mel Oliveira

    Primeiro lugar muito obrigada pela atenção e parabéns pelos artigos!
    Nossa faz tempo q procuro ajuda e meu xml eu gerei lendo teus artigos, mas esse erro nao consigo achar!

    A interpretação XML falhou: erro de sintaxe (Linha: 1, Caractere: 0)

    Refazer documento como HTML
    Erro:
    missing root element
    Especificação:
    http://www.w3.org/TR/REC-xml/

    Coloquei aqui!

    http://pastebin.com/c0Q7Gd13

    1. Rafael Clares

      Entendi, sinceramente, nf-e é muito chato e neste caso é melhor usar um método mais fácil de visualizar os nós.
      Usar o método que você utilizou é realmente o “legal” mas infelizmente fica ruim de encontrar um problema porque não conseguimos ver os nós.
      Então, neste caso aconselho usar diferente, criei um modelo que você vai precisar terminar, eu até comecei a fazer mas tá corrido aqui.
      É bem, simples, basta substituir os valores, eu já fiz uns 5 ou 6 para você.
      Vai lá: http://pastebin.com/ZhMeLhuJ

      1. Mel Oliveira

        Obrigada rafael mas esse projeto nao ja ta no meu TCC não posso mais mudar!
        Mas se tiver alguém q consiga achar o erro eu agradeço muito!

  29. Felipe

    como faço para mudar: topo para

    preciso instalar algo?

    1. Rafael Clares

      Não entendi a pergunta.

      1. Alexandre Athayde

        Rafael, primeiramente parabéns, muito boa explicação.
        No meu caso ele funcionou em parte, eu tenho um sql que me retorna 7 registros, porém no xlm, traz somente 3 registros e no final traz 3 tag’s fechadas sem necessidade.
        Tipo assim->

        Linha 1 – Não aparece no XML
        Linha 2 – Aparece no XML
        Linha 3 – Não aparece no XML
        Linha 4 – Aparece no XML
        Linha 5 – Não aparece no XML
        Linha 6 – Aparece no XML
        Linha 7 – Não aparece no XML

        e o final as 3 Tag’s:

        Vc tem alguma idéia do que pode estar acontecendo?

        1. Rafael Clares

          Alexandre, se colocar o trecho PHP no pastebin eu talvez eu possa ajudar, só lendo seu comentário não consigo nem ter ideia. No entanto, me parece que na hora de gerar o XML o conteúdo que deveria preencher as tags está ficando ausente, deixando as nós vazios, tem que ver o que está retornando do banco, se tem caracter especial esse valor, etc… qual tipo de dado deveria preencher esses nós? Como está no banco, é char, int, tem algum conteúdo especial?

  30. Leo

    Brother, joia?
    Como gravo um XML porém NOUTRA PASTA?
    Consegui gravar o xml, porém so consigo gravar na mesma pasta. Nao lembro onde peguei o código mas coloco aqui a parte que acredito fazer isto:

    $Writer->endElement();

    $Output = $Writer->outputMemory ( true ) ;
    $fHandle = fopen ( ‘./teste.xml’ , ‘w+’ ) ;
    fwrite ( $fHandle , $Output ) ;
    fclose ( $fHandle ) ;

    header ( ‘Content-Type: text/xml;charset=utf-8’ ) ;
    header(‘Expires: 0’);
    header(‘Cache-Control: no-cache, no-store, must-revalidate, post-check=0, pre-check=0’);
    header(‘Pragma: no-cache’);
    echo $Output;
    ?>

    Este é o fim do arquivo PHP.
    Bem, não sei se receberei via e-mail o link dessa sua resposta quando voce receber.
    Caso não. se puder me avisar.
    É que estou MUITO precisando desta resposta e também postei noutros blogs/foruns.

    Grato
    Léo

    1. Rafael Clares

      Leo, esse trecho não está gravando e sim exibindo o XML.
      Para gravar deve alterar o trecho:

      header ( ‘Content-Type: text/xml;charset=utf-8′ ) ;
      header(‘Expires: 0′);
      header(‘Cache-Control: no-cache, no-store, must-revalidate, post-check=0, pre-check=0′);
      header(‘Pragma: no-cache’);
      echo $Output;

      Por

      $file = fopen(‘foo.xml’,’w+’);
      fwrite($file,$xml->outputMemory(true));
      fclose($file);

      Veja o exemplo completo para gravação em:

      http://clares.com.br/gerar-xml-com-php5-e-xmlwriter/

  31. Renato

    Ressuscitando o post Clares, mas foi o melhor que já encontrei sobre o assunto, porém me deparo com um erro que não consigo solucionar, ‘error on line 2 at column 6: XML declaration allowed only at the start of the document’, é comum você encontrar esse erro? alguma idéia? eu fiz o teste e copiei o código inteiro do seu primeiro exemplo como ele está, e recebo sempre a mesma mensagem.

    1. Rafael Clares

      Renato, copiar o código não é a melhor opção, perceba que quando você copia alguns caracteres especiais são copiados juntos.
      O que certamente está ocorrendo é que ao invés das aspas deve estar com caracter especial que se parece muito.
      Confira as aspas e aconselho você digitar novamente todas elas ou usar “Susbstituir” do seu editor.

  32. Paulo Henrique

    Rafael, gostaria de saber se tem como salvar esse arquivo xml em dois diretórios diferentes.

    1. Rafael Clares

      Sim, basta repetir a linha de comando que salva o arquivo.
      $dom->save(“path/1.xml”);
      $dom->save(“other/path/1.xml”);

  33. Eric Souza

    Olá Rafael poderia me ajudar não estou conseguindo inserir os que é ditado nesses input do meu index no arquivo xml.

    Meu index.php

    1. Rafael Clares

      Onde você escreveu o comentário está escrito que “comentários com códigos serão ignorados” e você não leu isso, postou 2 vezes o mesmo comentário com códigos.
      Talvez seja falta de atenção o problema aí rs

      No seu código está faltando recuperar os dados do post;

      $nomeElm = $document->createElement(“nome”, $_POST[‘nome’]);
      $precoElm = $document->createElement(“preco”, $_POST[‘preco’]);

      abs

  34. Jaison Martins

    Bom dia, queria saber como faço um formulário php que quando eu click em gerar ele salve isso no xml? ja procurei mais não achei nada, como o codigo de como gera com php o xml, mas queria entende como levo do formulario para o xml?

  35. rafael stromdahl

    Blz Rafael, estou utlizando o teu código num plugin do wordpress, o contact form 7.

    eu preciso que quando o usuário preencha o formulário, os dados sejam salvos em um xml que irá para uma aplicação que consome um web service.

    o script funcionou muito bem exceto por um pequeno detalhe:

    não posso gerar o arquivo com um nome específico, senão sempre que alguem preencher o form irá sobrescrever o arquivo. Então coloquei a variável que recebe o nome e concatenei com a extensão .xml. até aqui beleza, o problema é que não consigo salvar em um diretório e nem em um endereço específico. meu código para salvar ficou assim:

    $dom->save($cf7Nome.”.xml”);

    A variável $cf7Nome é o campo nome. Eu não consigo por exemplo fazer algo do tipo:

    $dom->save(“path/” $cf7Nome. “.xml”); —> isso dá erro

    pode me dar uma luz?

Os comentários estão encerrados.