Olá, tenho um pequeno servidor CentOS rodando o MySQL que precisa ser atualizado diariamente com algumas informações que me são passadas via arquivo XML.
O XML tem a seguinte estrutura:
<?xml version="1.0"?>
01
898002342517744
023805
MARIA MARIA MARIA
8888888888
03/08/2011
12:07
1
016326
CAROLINA CAROLINA
0302
TESTE
11
RECEPCAO
01
898001928493418
033165
MANOEL MANOEL
8999999999
09/08/2011
11:08
1
015525
POLYANNA POLYANNA
0104
TESTE
14
RECEPCAO
e por ai vai.
Sou totalmente leigo em PHP porém encontrei em um site algo parecido com o que quero fazer: http://phpbr.wordpress.com/2007/07/07/xml-to-mysql-transformando-um-arquivo-xml-em-queries-sql-e-blablabla/
Tentei adaptar às minhas necessidades, mas não estou conseguindo, no meu caso o script ficou assim:
<?php
$banco = 'xml2mysql';
$host = 'localhost'; // host
$usuario = 'root'; // usuario
$senha = 'minha_senha'; // senha
// connectamos ao host e selecionamos o banco
mysql_connect($host, $usuario, $senha);
mysql_select_db($banco);
// esta variavel sera a query utilizada para insercao dos
// dados no banco, tendo o %d substituido pelo id_exemplo
// e o %s substituido pela descricao
$query = 'insert into exemplo (GM8_DTATEND, GCS_NOMLOC, GM8_HORAGE, RA_NOME, GM8_MATRIC, GM8_CELULAR) values ("%s", "%s", "%s", "%s", "%s")';
// carregamos o conteudo do arquivo XML
$xml = file_get_contents('demo2.xml');
// transformamos o XML em um objeto, para que possamos trabalhar
// de forma mais simples com ele
$sxml = new SimpleXMLElement($xml);
// aqui iteramos por todo o XML:
// a cada iteracao, $line ira conter um objeto to tipo
// SimpleXMLElement, sendo o equivalente a:
//
//
// 1
// Primeiro exemplo
//
//
foreach ($sxml as $linhaAtual) {
// aqui vamos obter cada item do xml que seria referente
// ao campo da tabela.
// Necessario cast pelo fato de que a propriedade do objeto
// tambem é um objeto do tipo SimpleXMLElement
$data = (string) $linhaAtual->GM8_DATEND;
$local = (string) $linhaAtual->GCS_NOMLOC;
$hora = (string) $linhaAtual->GM8_HORAGE;
$nome = (string) $linhaAtual->RA_NOME;
$matricula = (string) $linhaAtual->GM8_MATRIC;
$celular = (int) $linhaAtual->GM8_CELULAR;
// aqui preparamos a query para ser utilizada
$tmpQuery = sprintf($query, $data, $local, $hora, $nome, $matricula, $celular);
// exibimos a query que será executada
echo sprintf('Executando query: %s%s', $tmpQuery, "\n");
// e aqui executamos a query
mysql_query($tmpQuery);
}
Antes de rodar eu criei o banco "xml2mysql" e a tabela "exemplo":
mysql> show tables;
+---------------------+
| Tables_in_xml2mysql |
+---------------------+
| exemplo |
+---------------------+
1 row in set (0.00 sec)
mysql> SHOW INDEX FROM xml2mysql.exemplo;
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| exemplo | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
1 row in set (0.00 sec)
Criei as colunas na tabela e aproveitei e introduzi apenas uma linha na mão:
mysql> SELECT * FROM exemplo;
+----+------------+-------+-------+---------+------------+----------+
| id | data | local | hora | nome | matricula | celular |
+----+------------+-------+-------+---------+------------+----------+
| 1 | 23/10/2010 | prt | 12:00 | teste01 | 12345 | 77777777 |
+----+------------+-------+-------+---------+------------+----------+
1 row in set (0.00 sec)
Mas ao rodar o script PHP, ele executa, mas não mostra o número do celular corretamente e nada vai parar no MySQL:
[localdomain tmp]# php test.php
Executando query: insert into exemplo (GM8_DTATEND, GCS_NOMLOC, GM8_HORAGE, RA_NOME, GM8_MATRIC, GM8_CELULAR) values (0, "RECEPCAO ", "12:07", "CAROLINA CAROLINA ", "898002342517744", "0")
Executando query: insert into exemplo (GM8_DTATEND, GCS_NOMLOC, GM8_HORAGE, RA_NOME, GM8_MATRIC, GM8_CELULAR) values (0, "RECEPCAO ", "11:08", "POLYANNA POLYANNA", "898001928493418", "0")
[localdomain tmp]#
Alguém saberia me informar onde está o erro?
Obrigado,
João Marcelo
- Home
- >
- Fórum
- >
- Profissional
- >
- Programação, Sc...
- >
- Script para importar XML...
Coloca um mysql_erro() nessa linha
$query = 'insert into exemplo (GM8_ID, GM8_DTATEND, GCS_NOMLOC, GM8_HORAGE, RA_NOME, GM8_MATRIC, GM8_CELULAR) values (%d, "%s", "%s", "%s", "%s", "%s")';
ficando assim $query = 'insert into exemplo (GM8_ID, GM8_DTATEND, GCS_NOMLOC, GM8_HORAGE, RA_NOME, GM8_MATRIC, GM8_CELULAR) values (%d, "%s", "%s", "%s", "%s", "%s")' . mysql_erro();
Para poder exibir os erros de envio de arquivos.
waldony, obrigado pela ajuda. Tentei fazer o que você sugeriu, mas ocorreu o seguinte:
[localdomain tmp]# php test.php
PHP Fatal error: Call to undefined function mysql_erro() in /tmp/test.php on line 15
João Marcelo disse: waldony, obrigado pela ajuda. Tentei fazer o que você sugeriu, mas ocorreu o seguinte:
[localdomain tmp]# php test.php
PHP Fatal error: Call to undefined function mysql_erro() in /tmp/test.php on line 15
a função é mysql_error()
Obrigado jcferranti, percebi depois :P voltei aqui para postar o resultado, porém você foi mais rápido que eu.
Desculpem novamente a noobisse, mas onde será gerado o aquivo de log com o erro? Procurei em /var/log/mysql.log e /var/lib/mysql nada. Procurei também por arquivos com a extensão .err e nada.
João Marcelo disse: Obrigado jcferranti, percebi depois :P voltei aqui para postar o resultado, porém você foi mais rápido que eu.
Desculpem novamente a noobisse, mas onde será gerado o aquivo de log com o erro? Procurei em /var/log/mysql.log e /var/lib/mysql nada. Procurei também por arquivos com a extensão .err e nada.
Mas não há log de erro, me diga uma coisa você definil a função?
Tenta defini-la, vou baixar aqui o script para tentar te ajudar melhor.
GM8_CELULA no arquivo xml não é o mesmo que GM8_CELULAR em
[php][/$celular = (int) $linhaAtual->GM8_CELULAR;
php]
Para que a dica dada pelos colegas funcionasse é necessário que você mude a ordem de execução de algumas linhas, alem disso não sei se o mysql_error() pode ser executado dentro de mysql_query(). Eu simplesmente acrescentaria uma nova linha
[php]echo "\n
Mysql error: " .mysql_error() . "\n
"[/php]
depois de
[php]mysql_query($tmpQuery);
[/php]
Descoberto o bug é claro que a linha deve ser eliminada ou mostrada apenas de forma condicional ...
Outra dica: simplexml_load_file() poderia encurtar em 1 comando seu código (claro que se nem funciona ainda não faz sentido você tentar "melhorar" o código).
Vou modificar o script e depois posto o resultado.
Ximenes, como disse, sou noob em PHP, tudo que fiz tá aí.
João Marcelo disse: jofrelscalvet, obrigado pela dica, realmente o CELULA passou batido
Vou modificar o script e depois posto o resultado.
Ximenes, como disse, sou noob em PHP, tudo que fiz tá aí.
Encontrei um Script na net que talvez possa te ajudar. ele é muito bom testei e deu certo.
1.)extrairCamposArquivoXML($campos, $elemento, $i) > Extrai os campos do elemento do arquivo XML, usados para inserção na tabela da base de dados.
private function extrairCamposArquivoXML($campos, $elemento, $i){
$doc = new DomDocument;
$doc->Load($this->arquivoXML); // Carrega o arquivo XML com um arquivo DOMDocument
$items = $doc->getElementsByTagName($elemento); //Seleciona o elemento ou tabela a ser importada
$valor = array();
foreach ($campos as $campo) {
$valor[] = "'" . $items->item($i)->getElementsByTagName($campo)->item(0)->nodeValue . "'"; //Extrai o valor para cada campo passado para extração
}
$value = ' (';
$value .= implode(',', $valor);
$value .= ') ';
return $value; //Retorna string no seguinte formato ('valor1','valor2','valor3','valor4',...,'valorn')
}
2.)extrairQuantidadeItensArquivoXML($elemento) > Extrai o número total de registros do elemento XML.
private function extrairQuantidadeItensArquivoXML($elemento){
$doc = new DomDocument;
// Carrega o arquivo XML com um arquivo DOMDocument
$doc->Load($this->arquivoXML);
$items = $doc->getElementsByTagName($elemento);
return $items->length; //Retorna a quantidade de elementos ou registros
}
3.)criarQueryImportacaoXML($campos, $elemento, $tabela, $colunas, $quantidade) > Constrói a query SQL para inserção na base de dados.
private function criarQueryImportacaoXML($campos, $elemento, $tabela, $colunas, $quantidade){
$query = "insert into $tabela (";
$query .= implode (",",$colunas);
$query .= ") values ";
$query .= $this->extrairCamposArquivoXML($campos, $elemento, $quantidade);
echo $query;
return $query; Retorna a query no seguinte formato insert into $tabela (campo1,campo2,campo3,...,campon) values ('valor1','valor2','valor3','valor4',...,'valorn')
}
Estas 3 funções são a base da importação, pois são responsável pela extração dos dados XML e criação da query SQL, abaixo o script completo (Classe importação, para exemplo).
<?php
// Informações da Classe Importação
// Versão 0.1a
// Data de criação 27/12/2010
// Última modificação 27/12/2010
// Classe construída para importação da base de dados do Publique para o CMS Unideia
// Após a extração colocar o arquivo XML no mesmo lugar do importacao.php, depois só executar no browser ou prompt
// Desenvolvida por
// Diego Muniz Cerqueira
// Programador Web
// Octonal Comercio e Serviços de Informática Ltda.
// +55 21 3296-9328
// [email]dcerqueira@allnetgroup.com.br[/email]
// www.allnetgroup.com.br
// Microsoft Crm Certified Partner
// Microsoft Infrastructure Certified Partner
// Observações
// - Ao instanciar a classe tem que se informar se deseja ativar o SQL, o nome da base de dados e o nome do arquivo XML.
// - Para teste mude valor de $ativar_conexao para false. Ex.: $importar = new importacao(false, 'diego', 'database.xml');
// Descrição dos métodos
// __construct($ativar, $bd, $arquivo) > Método construtor da classe.
// construirBase() > Método responsável por criar a nova base de dados e as tabelas a serem utilizadas.
// executarSQL($query) > Recebe a string SQL para execução.
// extrairCamposArquivoXML($campos, $elemento, $i) > Extrai os campos do elemento do arquivo XML, usados para inserção na tabela da base de dados.
// extrairQuantidadeItensArquivoXML($elemento) > Extrai o número total de registros do elemento XML.
// criarQueryImportacaoXML($campos, $elemento, $tabela, $colunas, $quantidade) > Constrói a query SQL para inserção na base de dados.
// importarUsuarios() > Responsável por importar os usuários do arquivo XML para a base de dados MySQL no novo formato.
// importarMaterias() > Responsável por importar as matérias do arquivo XML para a base de dados MySQL no novo formato.
// importarSecao() > Responsável por importar as seções do arquivo XML para a base de dados MySQL no novo formato.
// principal() > Controla a execução do código, método principal, único com possibilidade de acesso externo.
class Importacao{
private $ativar_conexao;
private $conexao;
private $base;
private $arquivoXML;
public function __construct($ativar, $bd, $arquivo){
$this->ativar_conexao = $ativar;
$this->base = $bd;
$this->arquivoXML = $arquivo;
}
private function construirBase(){
if ($this->ativar_conexao == true) {
$this->conexao = mysql_connect("localhost","root","") or die('falha ao conectar');
$query = 'CREATE DATABASE IF NOT EXISTS diego;';
if(!mysql_query($query,$this->conexao)) {
echo mysql_error().'
falha ao criar base de dados
';
}
mysql_select_db($this->base,$this->conexao) or die($msg[1]);
$query = "CREATE TABLE IF NOT EXISTS `usuario` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`nome` varchar(250) DEFAULT NULL,
`email` varchar(250) DEFAULT NULL,
`login` varchar(250) DEFAULT NULL,
`senha` varchar(50) DEFAULT NULL,
`ativo` tinyint(1) NOT NULL,
`perfil` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;";
if(!mysql_query($query,$this->conexao)) {
echo mysql_error().'
falha ao criar tabela
';
}
$query = "CREATE TABLE IF NOT EXISTS `materia` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`estado` int(10) DEFAULT NULL,
`data` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`idSecao` int(10) DEFAULT NULL,
`titulo` varchar(250) DEFAULT NULL,
`idUsuario` int(10) DEFAULT NULL,
`subtitulo` longtext,
`texto` longtext,
`imagem` varchar(250) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;";
if(!mysql_query($query,$this->conexao)) {
echo mysql_error().'
falha ao criar tabela
';
}
$query = "CREATE TABLE IF NOT EXISTS `secao` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`nome` varchar(250) DEFAULT NULL,
`tag` varchar(250) DEFAULT NULL,
`descricao` longtext,
`idSecaoPai` int(10) DEFAULT NULL,
`link` varchar(250) DEFAULT NULL,
`ordem` varchar(250) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;";
if(!mysql_query($query,$this->conexao)) {
echo mysql_error().'
falha ao criar tabela
';
}
}
}
private function executarSQL($query){
if ($this->ativar_conexao == true) {
if(!mysql_query($query,$this->conexao)) {
echo mysql_error().'
falha ao inserir dados
';
} else {
echo '
registro copiado
';
}
}
}
private function extrairCamposArquivoXML($campos, $elemento, $i){
$doc = new DomDocument;
// Carrega o arquivo XML com um arquivo DOMDocument
$doc->Load($this->arquivoXML);
$items = $doc->getElementsByTagName($elemento);
$valor = array();
foreach ($campos as $campo) {
$valor[] = "'" . $items->item($i)->getElementsByTagName($campo)->item(0)->nodeValue . "'";
}
$value = ' (';
$value .= implode(',', $valor);
$value .= ') ';
return $value;
}
private function extrairQuantidadeItensArquivoXML($elemento){
$doc = new DomDocument;
// Carrega o arquivo XML com um arquivo DOMDocument
$doc->Load($this->arquivoXML);
$items = $doc->getElementsByTagName($elemento);
return $items->length;
}
private function criarQueryImportacaoXML($campos, $elemento, $tabela, $colunas, $quantidade){
$query = "insert into $tabela (";
$query .= implode (",",$colunas);
$query .= ") values ";
$query .= $this->extrairCamposArquivoXML($campos, $elemento, $quantidade);
echo $query;
return $query;
}
private function importarUsuarios(){
$elemento = 'Actor';
$campos = array('ActorID','ActorName','Login','Password','Email','IsActive');
$tabela = 'usuario';
$colunas = array('id','nome','login','senha','email','ativo');
for ($i=0; $i < $this->extrairQuantidadeItensArquivoXML($elemento); $i++) {
$this->executarSQL($this->criarQueryImportacaoXML($campos, $elemento, $tabela, $colunas, $i));
echo '';
}
}
private function importarMaterias(){
$elemento = 'Info';
$campos = array('InfoID','Title','Summary','ActorID','HeadLineImage','FullText', 'State', 'SectionID');
$tabela = 'materia';
$colunas = array('id','titulo','subtitulo','idUsuario','imagem','texto', 'estado', 'idSecao');
for ($i=0; $i < $this->extrairQuantidadeItensArquivoXML($elemento); $i++) {
$this->executarSQL($this->criarQueryImportacaoXML($campos, $elemento, $tabela, $colunas, $i));
echo '';
}
}
private function importarSecao(){
$elemento = 'Section';
$campos = array('SectionID','SectionName','Description','URL','infoOrderCriteria','ParentSectionID', 'tag');
$tabela = 'secao';
$colunas = array('id','nome','descricao','link','ordem','idSecaoPai', 'tag');
for ($i=0; $i < $this->extrairQuantidadeItensArquivoXML($elemento); $i++) {
$this->executarSQL($this->criarQueryImportacaoXML($campos, $elemento, $tabela, $colunas, $i));
echo '';
}
}
public function principal(){
$this->construirBase();
echo "===========================================
";
echo "=== IMPORTANDO DADOS DOS USUÁRIOS =======
";
echo "===========================================
";
$this->importarUsuarios();
echo "===========================================
";
echo "=== IMPORTANDO DADOS DAS MATERIAS =======
";
echo "===========================================
";
$this->importarMaterias();
echo "===========================================
";
echo "=== IMPORTANDO DADOS DAS SECOES =======
";
echo "===========================================
";
$this->importarSecao();
echo "===========================================
";
echo "IMPORTAÇÃO ENCERRADA CONFIRA A BASE DE DADOS
";
echo "===========================================
";
}
}
$importar = new Importacao(false, 'diego', 'database.xml');
$importar->principal();
?>
Creditos à Diego Muniz Cerqueira
Mesmo assim seu script está anotado e com certeza será estudado.
Obrigado novamente.
Abraços,
João Marcelo
João Marcelo disse: Ximenes, muito obrigado pela ajuda, mas com a dica do jofrelscalvet para mostrar o erro do script eu já consegui resolver. O problema era que, apesar do no site a linha " $query = 'insert into exemplo (GM8_DTATEND, GCS_NOMLOC, GM8_HORAGE, RA_NOME, GM8_MATRIC, GM8_CELULAR) values ("%s", "%s", "%s", "%s", "%s")'; " fazer referência ao XML, na verdade ela deve fazer aos campos da tabela exemplo MySQL. Agora isso parece óbvio, mas demorei para perceber.
Mesmo assim seu script está anotado e com certeza será estudado.
Obrigado novamente.
Abraços,
João Marcelo
Valeu posta ai o script todo se puder, e não esquece de colocar resolvido no titulo para futuras duvidas.
Abraço...
Segue o script:
<?php
// modificado por JM
$banco = 'xml2mysql';
$host = '127.0.0.1'; // host
$usuario = 'root'; // usuario
$senha = 'senha'; // senha
mysql_connect($host, $usuario, $senha);
mysql_select_db($banco);
$query = 'insert into exemplo (data, local, hora, nome, matricula, celular) values ("%s", "%s", "%s", "%s", "%s", "%s")';
$xml = file_get_contents('demo.xml');
$sxml = new SimpleXMLElement($xml);
foreach ($sxml as $linhaAtual) {
$data = (string) $linhaAtual->GM8_DTATEND;
$local = (string) $linhaAtual->GCS_NOMLOC;
$hora = (string) $linhaAtual->GM8_HORAGE;
$nome = (string) $linhaAtual->RA_NOME;
$matricula = (string) $linhaAtual->GM8_MATRIC;
$celular = (string) $linhaAtual->GM8_CELULA;
$tmpQuery = sprintf($query, $data, $local, $hora, $nome, $matricula, $celular);
echo sprintf('Executando query: %s%s', $tmpQuery, "\n");
mysql_query($tmpQuery);
echo "\n
Mysql error: " .mysql_error() . "\n
";
}
Preferi deixar a última linha como aviso de minha noobisse :/
Obrigado a todos!