Olá,
Mais um exemplo de como gerar XML com PHP5, neste caso iremos utilizar a Classe nativa do PHP5 o XMLWriter para gerar a saída XML formatada.
Este exemplo, sem dúvidas é bem mais simples que o anterior que utiliza o DOM ou SimpleXML.
Vejamos o código:
<?
# Instancia do objeto XMLWriter
$xml = new XMLWriter;
# Cria memoria para armazenar a saida
$xml->openMemory();
# Inicia o cabeçalho do documento XML
$xml->startDocument( '1.0' , 'iso-8859-1' );
# Adiciona/Inicia um Elemento / Nó Pai <item>
$xml->startElement("item");
# Adiciona um Nó Filho <quantidade> e valor 8
$xml->writeElement("quantidade", 8);
# Adiciona um Nó Filho <preco> e valor 110
$xml->writeElement("preco", 110);
# Finaliza o Nó Pai / Elemento <Item>
$xml->endElement();
# Configura a saida do conteúdo para o formato XML
header( 'Content-type: text/xml' );
# Imprime os dados armazenados
print $xml->outputMemory(true);
# Salvando o arquivo em disco
# retorna erro se o header foi definido
# retorna erro se outputMemory já foi chamado
$file = fopen('foo.xml','w+');
fwrite($file,$xml->outputMemory(true));
fclose($file);
?>
Obs: A chamada ao método $xml->outputMemory() descarrega os dados da memória então você só consegue chama-lo uma vez, logo, para salvar o arquivo você não pode ter chamado este método ainda.
Para salvar o arquivo corretamente você deve comentar as linhas abaixo:
# header( ‘Content-type: text/xml’ );
# print $xml->outputMemory(true);
Comente as linhas abaixo para apenas exibir o XML no browser:
# $file = fopen(‘foo.xml’,'w+’);
# fwrite($file,$xml->outputMemory(true));
# fclose($file);
Referência: http://br.php.net/manual/pt_BR/book.xmlwriter.php
Por enquanto é isso galera, bom divertimento e até mais.
Boa camarada!
Ótimo exemplo. Claro e preciso!
Parabéns!
Prezado Rafael,
Necessito de uma ajudinha urgente.
Tenho um form em html com 4 campos que tem como action uma página em php que exibe os dados digitados na página html.
Além de exibir os dados, necessito gerar um arquivo XML com os dados digitados no form.
Agradeço desde já a ajuda.
Mônica você precisa apenas substituir os dados do xml proposto neste exemplo pelos dados do post, ex:
Supondo que os campos do formulário sejam nome, email e fone,
<?php
extract($_POST);
// aqui o inicio do xml como no exemplo
.
.
// aqui os elementos com os valores dos campos
$xml->writeElement("nome", "$nome");
$xml->writeElement("email", "$email");
$xml->writeElement("fone", "$fone");
.
.
//restande do xml como no exemplo
?>
Obs: o extract($_POST) cria automaticamente as var $nome, $email e $fone com os valores vindos do XML
Espero ter ajudado, mesmo pq eu não encontrei um forma de simplificar o exemplo e a explicação.
Boa sorte
Rafael, desculpe incomodá-lo.
A minha página de ação ficou assim:
openMemory();
# Inicia o cabeçalho do documento XML
$xml->startDocument( ’1.0′ , ‘iso-8859-1′ );
# Adiciona/Inicia um Elemento / Nó Pai
#$xml->startElement(“item”);
$xml->startElement(“Automóvel”);
$xml->writeElement(“modelo”, “$modelo”);
$xml->writeElement(“cor”, “$cor”);
$xml->writeElement(“fabricante”, “$fabricante”);
$xml->writeElement(“ano”, “$ano”);
# Finaliza o Nó Pai / Elemento
$xml->endElement();
# Configura a saida do conteúdo para o formato XML
header( ‘Content-type: text/xml’ );
# Imprime os dados armazenados
print $xml->outputMemory(true);
# Salvando o arquivo em disco
# retorna erro se o header foi definido
# retorna erro se outputMemory já foi chamado
#$file = fopen(‘foo.xml’,'w+’);
$file = fopen(‘auto.xml’,'w+’);
fwrite($file,$xml->outputMemory(true));
fclose($file);
?>
E infelizmente não acontece nada.
Mais uma vez muito obrigada.
Mônica, não faltou o extract($_POST) ?
extract($_POST);
openMemory();
# Inicia o cabeçalho do documento XML
$xml->startDocument( ’1.0′ , ‘iso-8859-1′ );
# Adiciona/Inicia um Elemento / Nó Pai
#$xml->startElement(“item”);
$xml->startElement(“Automóvel”);
$xml->writeElement(“modelo”, “$modelo”);
$xml->writeElement(“cor”, “$cor”);
$xml->writeElement(“fabricante”, “$fabricante”);
$xml->writeElement(“ano”, “$ano”);
# Finaliza o Nó Pai / Elemento
$xml->endElement();
# Configura a saida do conteúdo para o formato XML
header( ‘Content-type: text/xml’ );
# Imprime os dados armazenados
print $xml->outputMemory(true);
# Salvando o arquivo em disco
# retorna erro se o header foi definido
# retorna erro se outputMemory já foi chamado
#$file = fopen(‘foo.xml’,’w+’);
$file = fopen(‘auto.xml’,’w+’);
fwrite($file,$xml->outputMemory(true));
fclose($file);
?>
Perdão, segue o código. Coloquei o extract($_POST) sim. Veja abaixo:
openMemory();
# Inicia o cabeçalho do documento XML
$xml->startDocument( ’1.0′ , ‘iso-8859-1′ );
# Adiciona/Inicia um Elemento / Nó Pai
#$xml->startElement(“item”);
$xml->startElement(“Automóvel”);
$xml->writeElement(“modelo”, “$modelo”);
$xml->writeElement(“cor”, “$cor”);
$xml->writeElement(“fabricante”, “$fabricante”);
$xml->writeElement(“ano”, “$ano”);
# Finaliza o Nó Pai / Elemento
$xml->endElement();
# Configura a saida do conteúdo para o formato XML
header( ‘Content-type: text/xml’ );
# Imprime os dados armazenados
print $xml->outputMemory(true);
# Salvando o arquivo em disco
# retorna erro se o header foi definido
# retorna erro se outputMemory já foi chamado
#$file = fopen(‘foo.xml’,'w+’);
$file = fopen(‘auto.xml’,'w+’);
fwrite($file,$xml->outputMemory(true));
fclose($file);
?>
E nada acontece.
Desculpe pelo incômodo. Sou nova em php.
Obrigada.
Apesar de não aparecer no código acima tem o extract($_POST) e a Instancia do objeto XMLWriter
$xml = new XMLWriter;
Obrigada.
Mônica, olha só ou você imprime na tela ou salva em disco, entendeu ? os 2 não vai rolar, ao menos não nessa ordem.
Se você precisa salvar em disco, basta fazer:
<?
extract($_POST);
$xml = new XMLWriter;
$xml->openMemory();
$xml->startDocument( '1.0' , 'iso-8859-1' );
$xml->startElement("Automovel");
$xml->writeElement("modelo", "$modelo");
$xml->writeElement("cor", "$cor");
$xml->writeElement("fabricante", "$fabricante");
$xml->writeElement("ano", "$ano");
$xml->endElement();
//header( 'Content-type: text/xml' );
//print $xml->outputMemory(true);
$file = fopen('auto.xml','w+');
fwrite($file, $xml->outputMemory(true));
fclose($file);
?>
Se quer exibir na tela:
<?
extract($_POST);
$xml = new XMLWriter;
$xml->openMemory();
$xml->startDocument( '1.0' , 'iso-8859-1' );
$xml->startElement("Automovel");
$xml->writeElement("modelo", "$modelo");
$xml->writeElement("cor", "$cor");
$xml->writeElement("fabricante", "$fabricante");
$xml->writeElement("ano", "$ano");
$xml->endElement();
header( 'Content-type: text/xml' );
print $xml->outputMemory(true);
?>
Testei os 2 com e funcionou corretamente, não se esqueça que para gravar no disco precisa da permissão de gravação no diretório.
Te mandei meu exemplo por email, mas por favor não faça perguntas por email, assim talvez possamos ajudar outras pessoas.
obs: os 2 não dá certo porque quando ocorre a primeira vez o $xml->outputMemory(true) ele libera da memória o conteúdo.
abraços
Funcionou certinho como vc falou.
Muito obrigada.
Rafael,
Tenho a seguinte situação:
Na página de ação (resultado.php) preciso exibir os dados digitados no form e depois gerar o xml com estes dados. Como não conheço muito PHP, pensei em fazer isso:
Sei que ainda vou precisar muito da sua ajuda mas não vou desistir de forma alguma!
Obrigada.
Mônica, o ideal é que o arquivo que gera o xml faça apenas isso, porque a saída dele é em XML e qualquer outra coisa irá atrapalhar a saída…
Evite colocar aqui nos comentários as tags < e > porque além de não aparecer acaba bagunçando o resto, não entendi o problema ainda,
vamos fazer assim, eu acredito que você esteja tentando de toda forma mas vamos abstrair algumas informações ok.
Então, você tem um formulário e quer que seja exibido seu conteúdo (digitado pelo usuário) e em seguida seja gravado no XML, é isso ?
O cara tem que confirmar após ser mostrado na tela ou ao mesmo tempo que mostra também grava o arquivo ?
O que você está fazendo é gravar o arquivo ou exibir? Se for exibir, o conteúdo deve ser exclusivamente o XML, se colocar outra coisa junto invalidará o XML.
Tenho um form (com um action=resultado.php) chamado cadastro.html com os campos: modelo, cor, fabricante e ano.
Após o seu correto preenchimento e clicar no botão Enviar sou direcionada a página resultado.php onde tenho que fazer duas coisas:
1) Exibir os dados digitados no form (cadastro.html);
2) Gravar estes dados num arquivo xml qualquer.
O usuário pode ou não confirmar a gravação, tanto faz. A ordem é o que interessa. Primeiro visualizo os dados e depois gravo no XML.
A minha dúvida é: Como fazer essas duas coisas?
Mais uma vez muito obrigada.
Vê se é isso que quer fazer:
<?php
extract($_POST);
print "Modelo: $modelo <br />";
print "Cor: $cor <br />";
print "Ano: $ano <br />";
print "Fabricante: $fabricante <br />";
$xml = new XMLWriter;
$xml->openMemory();
$xml->startDocument( '1.0' , 'iso-8859-1' );
$xml->startElement("Automovel");
$xml->writeElement("modelo", "$modelo");
$xml->writeElement("cor", "$cor");
$xml->writeElement("fabricante", "$fabricante");
$xml->writeElement("ano", "$ano");
$xml->endElement();
//header( 'Content-type: text/xml' );
//print $xml->outputMemory(true);
$file = fopen('auto.xml','w+');
fwrite($file, $xml->outputMemory(true));
fclose($file);
?>
É exatamente isso!
O meu erro foi ter colocado a exibição dos dados dentro de uma table.
Espero que a minha dúvida possa ajudar outras pessoas.
Mais uma vez muito obrigada.
Bom dia Rafael,
Tenho mais uma dúvida a respeito do que trocamos idéia ontem.
Meu XML tem que gerar a data em que o arquivo foi criado.
ex.
O que coloco em que posição no código????
Onde vai ter a data, no XML mesmo ou no nome do arquivo ? ex: auto_10_10_2010.xml
Mesmo pq se 2 pessoas cadastrarem ao mesmo tempo vai dar erro por que cada um estará criando o mesmo arquivo,
pense nisso, a data atual é:
$data = date(‘d/m/Y’); // reproduz 13/10/2010
$data = date(‘d-m-Y’); // reproduz 13-10-2010
Bem, acho que entendeu, você pode utilizar qualquer caracter para separar os números ali em date.
Bom dia Rafael,
A data tem que constar na página XML gerada pelo preenchimento do cadastro.
Portanto se entendi tenho que inserir essa linha dentro do código da página resultado.php que vc passou acima.
Vc poderia me dizer onde devo colocá-la? Já fiz alguns testes e deu erro.
Desculpe ficar te alugando mais estou mais acostumada com ASP e estou tendo dificuldade para fazer esse código no PHP.
Mais uma vez agradeço a força.
[ ]‘s
Mônica, sei que está sendo o mais direta possível mas confesso que ainda não sei onde você quer colocar esse valor, por isso fica difícil eu dizer onde deve colocar o código.
Se a data vai no XML, logo, você precisa de mais um elemento no XML, assim como tem o fabricante, ano, modelo, teria o data também.
Se a data não precisa ir no xml e você precisa saber quando o arquivo foi gerado, você pode colocar a data no nome do arquivo, assim irá armazenar os arquivos sem que sejam substituidos.
ex: na linha que grava o xml:
$file = fopen(‘auto.xml’,'w+’);
você pode alterar o nome colocando a data:
$nomeDoXML = date(‘dmY’).”.xml”;
$file = fopen(“$nomeDoXML”,’w+’);
assim, você terá os arquivos com nome dessa forma: 15102010.xml (15/10/2010);
tchau
Rafael, Boa tarde.
Precisava de um código que permita editar um registro de um arquivo xml, eu seleciono o item e os valores ficariam disponíveis em um form para edição…
Vc pode indicar alguma referência?
Obrigado.
Alysson, me desulpe não poder ajuda-lo com este código mas confesso que há algum tempo já que venho ensaiando pra escrever esse código,. infelizmente estou sem tempo e talvez no começo do ano eu o faça.; abs
Bom dia, estou tendo dificuldade ao criar o xml pois apresenta um erro , na qual estou pesquisando e gosaria de uma ajuda de vocês.
Segue abaixo o código com o erro.
# Instancia do objeto XMLWriter
$xml = new XMLWriter;
# Cria memoria para armazenar a saida
$xml->openMemory();
# Inicia o cabeçalho do documento XML
$xml->startDocument( ’1.0′ ,’iso-8859-1′);
$xml->setIndent(true);
# Adiciona/Inicia um Elemento / Nó Pai
$xml->startElement(“EMPRESA”);
$xml->writeElement(“CODIGO_EMPRE”,’254′);
$xml->writeElement(“CODIGO_AGENTE”,’356′);
$xml->writeElement(“DATA_CADASTRO”,’04/2011′);
$xml->writeElement(“OBSEMP”,’O processo de licenciamento ambiental das obras foi solicitado em 22/03/2010, sendo o termo não liberado’);
$xml->endElement();
$file = fopen(‘../Img/xml/teste1.xml’,'w+’);
fwrite($file,$xml->outputMemory(true));
fclose($file);
Apos executar aparece este erro:
Warning: XMLWriter::outputMemory() [xmlwriter.outputmemory]: output conversion failed due to conv error, bytes 0xE3 0x6F 0×20 0x6C
Quando retirei a metade do campo OBSEMP ele rodou , ou seja eu acho que o problema seja no tamnanho da string do $xml , gostaria de uma ajuda de vocês para resolver este problema.
Faça um teste retirando palavras com acentos e me retorne para eu poder te ajudar.
Abs
Obrigado pela ajuda, realmente era os acentos.
Os detalhes fazem a diferença.
Carlos, mas você precisa do texto com acento, não é ?
Altere a linha:
$xml->startDocument( ’1.0′ ,’iso-8859-1′);
Para:
$xml->startDocument( ’1.0′ ,’utf-8′);
E faça um teste para ver se irá gravar corretamente, o correto seria com iso-8859-1 mas não custa nada tentar!
abs
Pessoal,
estou com uma dificuldade, estou gerando o xml como vocês estavam falando acima, mais só que se eu acessar o sistema de outra maquina e tentar gerar o xml ele gera mais não me dar a opção de salvar no meu pc só salva no servidor e pronto. Como eu faço para poder salvar no servidor e fazer o download do xml de outro pc.
estou usando no final do arquivo o seguinte:
header(‘Content-Description: File Transfer’);
header(‘Content-Disposition: attachment; filename=”‘.$nome_xml.’”‘);
header(‘Content-Type: application/octet-stream’);
header(‘Content-Transfer-Encoding: binary’);
header(‘Content-Length: ‘ . filesize($arquivoLocal));
header(‘Cache-Control: must-revalidate, post-check=0, pre-check=0′);
header(‘Expires: 0′);
// Envia o arquivo para o cliente
readfile($arquivoLocal);
na maquina que o sistema se encontra funciona mais acessando de outro maquina não funciona
Bruno faça o seguinte:
$fileName = “foo.xml”;
$handler = fopen(“$fileName”,”w+”);
fwrite($handler,$xml->outputMemory(true));
header(“Pragma: public”);
header(“Expires: 0″);
header(“Cache-Control: must-revalidate, post-check=0, pre-check=0″);
header(“Cache-Control: private”,false);
header(“Content-type: application/force-download”);
header(“Content-Disposition: attachment; filename=\”$fileName\”");
header(“Content-Transfer-Encoding: binary”);
readfile(“$fileName”);
Teste em:
http://clareslab.com.br/learn/phptoxml/download.php
Mandei o arquivo no seu email :
Obs: não respondo dúvidas por email, na verdade, nem as leio.
Abraços
Bom dia,
Eu preciso armazenar uns dados de um form, está gravando certinho no xml, porem, cada vez que eu salvo um dado diferente, ele sobrescreve o antigo.
Como eu faço pra ele ir armazenando em sequencia?
Obrigado.
Marcelo, o ideal é usar o XML para armazenar o resultado de um consulta e poder utiliza-lo para transportar dados de uma aplicação para outra ou algo do tipo.;
Utilizar o XML como banco de dados é possível e também complexo, não tenho como escrever a aplicação para você mas segue a dica:
1 – você lê o XML atual
2 – transforma os dados do XML em array (procure no google XML2Array)
3 – adiciona a nova informação/registro no array
4 – salva os dados do array no XML
Seria básicamente isso!
Novamente venho pedir a ajuda, o problema relatado antes foi resolvido colocando o $xml->startDocument( ’1.0′ ,’utf-8′), mais preciso gerar em iso-8859-1, alguém sabe o porque não está gerando com acentos ???
# Instancia do objeto XMLWriter
$xml = new XMLWriter;
# Cria memoria para armazenar a saida
$xml->openMemory();
# Inicia o cabeçalho do documento XML
$xml->startDocument( ’1.0′ ,’iso-8859-1′);
$xml->setIndent(true);
# Adiciona/Inicia um Elemento / Nó Pai
$xml->startElement(“EMPRESA”);
$xml->writeElement(“CODIGO_EMPRE”,’254′);
$xml->writeElement(“CODIGO_AGENTE”,’356′);
$xml->writeElement(“DATA_CADASTRO”,’04/2011′);
$xml->writeElement(“OBSEMP”,’O processo de licenciamento ambiental das obras foi solicitado em 22/03/2010, sendo o termo não liberado’);
$xml->endElement();
$file = fopen(‘../Img/xml/teste1.xml’,’w+’);
fwrite($file,$xml->outputMemory(true));
fclose($file);
Apos executar aparece este erro:
Warning: XMLWriter::outputMemory() [xmlwriter.outputmemory]: output conversion failed due to conv error, bytes 0xE3 0x6F 0×20 0x6C
Então, deixa com utf-8 e na primeira linha do arquivo que gera e também no que lê o XML coloque
@header(‘Content-Type: text/html; charset=iso-8859-1′);
O problema que eu não tenho acesso onde lê o XML , só faço gerar e enviar.
É Carlos, daí fica um pouco ruim de te ajudar, infelizmente!
Bem,
Ja tive problemas parecidos, não sei dizer se essa solução ajuda, mas segue um link :
http://scriptbrasil.com.br/forum/index.php?showtopic=145992 ,
Pelo que entendi, vc esta recebendo dados em formato UTF , mas precisa imprimi-los em ISO-8859-1 , então imaginei que se achasse uma solução para conversão de um formato para o outro, tu poderias trabalhar antes os dados e depois criar teu xml sem problema, a solução é o link acima.
Excelente post! Ajudou muito, obrigadão!
Boa noite Rafael,
Parabéns pelo post, me ajudou muito, mas ainda me resta uma dúvida.
Como faço para editar este xml, incluir um novo nó ou remover?
Abçs
Jonatas, esse é um outro assunto, realmente!
Espero poder postar logo, enquanto isso leia os 2 novos posts sobre XML que eu criei!
Abraços
Boa noite, estou precisando de uma ajuda, preciso montar uma agenda de serviços no meu site onde eu tenho um calendário anual e gostaria que meus clientes ao clicar no dia desejado pudesse marcar o serviço com nome, telefone, dia ou semana, e o serviço (os) solicitados, e que caso queiram possam efetuar o pagamento do serviço (os) antecipadamente.
Att Mauricio Campos
Mauricio, se procurar no google por “PHP calendar” verá que já existem diversas soluções prontas com a maioria das características que mencionou!
Talvez você possa alterar/incluir mais recursos em uma delas. Fazer do zero talvez não seja a melhor opção no seu caso se você não quer ter gastos com o sistema!
Muito excelente esse tópico…
Só uma perguntinha, tem como eu colocar uma quebra de linha ou algo do tipo?
No caso, estou criando esse nó.
# –
$xml->writeElement(“fonts”, ‘
‘);
E o resultado dele fica assim:
Mas eu gostaria de que ele ficasse assim:
Tem como?
Não veio o código no comentário, de toda forma no XML é bom criar essas quebras ou conteúdo html utilizando <[CDATA;
look: http://php.net/manual/en/function.xmlwriter-write-cdata.php