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
Cara, como seria para LER um arquivo XML ?
Olá Michel, Leia em http://clares.wordpress.com/2008/08/17/ler-xml-com-php/
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
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.
Show de bola!!
Parabéns!!
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.. 😉
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.
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!
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,
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?
Olá Bruno, dê uma olhada nesse link:
http://us2.php.net/manual/pt_BR/function.simplexml-element-addChild.php
tem o que vc procura.
abs
Muito boa a dica! Simples e eficiente!
Parabéns!
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?????
Olá Jose Ricardo, então amigo para ajuda-lo eu precisaria saber de onde vem o $Dado01 e $Dado02.
Já tentou utilizar outro exemplo para gerar o XML?
Veja se consegue com esse http://clares.wordpress.com/2009/09/29/gerar-xml-com-php5-e-xmlwriter/
como faco para inserir atributos com api DOM
bom material amigo
Olá,ótimo artigo!
exatamente o que procurava.
Abraços.
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.
Diogo, basta comentar a linha abaixo:
$dom->save(“contatos.xml”)
abraços
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
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)
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!
desculpa ressussitar aki, mas eu to querendo adicionar uma coisa do tipo mas estou com umas dificuldades…se puder ajudar nesse sentido…vlws ae
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
Muito prático.
Me ajudou muito!
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.
o legal, muito bom esse post, foi de muito ajuda, obrigado.
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
Rapaz, não entendi muito bem não … você coloca um caracter e quer que apareça outro, é isso?
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
Valeu Matheus, pode deixar vou escrever sim, é que esse mês tem sido muito corrido. abs
Ele quer saber se deve colocar & ou & para exibir o “&”
No caso, o correto seria & creio eu.
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”);
?>
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!
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
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.
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
Obrigado, você me ajudou muito.
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?
Precisaria ver o seu código PHP para entender o que há!
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?
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?
Isso, eu gostaria de enviar o XML como anexo sem precisar salvar ele localmente no servidor
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
Eu postei um problema aqui, mas nao acho mais, foi apagado?
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.
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
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
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!
como faço para mudar: topo para
preciso instalar algo?
Não entendi a pergunta.
Olá Rafael, como faço para criar um nó FILHO dentro de outro??
Ex: http://pastebin.com/qpwdY6hu
Fe, tem outro post que está exatamente como você deseja, inclusive o exemplo do nó filho.
http://clares.com.br/gerando-xml-com-php/
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?
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?
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
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/
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.
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.
Rafael, gostaria de saber se tem como salvar esse arquivo xml em dois diretórios diferentes.
Sim, basta repetir a linha de comando que salva o arquivo.
$dom->save(“path/1.xml”);
$dom->save(“other/path/1.xml”);
Olá Rafael poderia me ajudar não estou conseguindo inserir os que é ditado nesses input do meu index no arquivo xml.
Meu index.php
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
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?
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?