Pular para o conteúdo principal

Lazarus - Criando XML a partir de um DataSet

Sabemos que um documento XML pode ser criado manipulando strings e arquivos texto. Esta opção não é aconselhável, pois é difícil garantir que o documento seja bem formado. A melhor forma de fazer isso é usar DOM (Modelo Objeto de Documento). Já usamos esse padrão para ler um documento XML no artigo anterior.
Para ilustrar a criação de um documento vamos implementar uma aplicação que gera um XML a partir dos registros de um DataSet. Para isso vamos usar nosso banco de dados SQLite de exemplos anteriores e vamos usar ZeosLib. Mas pode ser usado qualquer conjunto de componentes, inclusive SQLdb.
Coloque então um TZConnection no form, ou num Data Module. Defina a propriedade Database com o banco SQLite, ou qualquer outro. Defina a propriedade Protocol com sqlite-3.
Coloque também um TZReadOnlyQuery e defina Name como queCidade. Em Connection selecione o TZConnection. Na propriedade SQL digite SELECT * FROM CIDADE.
Insira um botão, que vai executar a criação do XML.

Na cláusula uses acrescente as units DOM e XMLWrite.

Agora vamos criar o código que efetivamente irá criar o XML. A idéia é criar um procedimento genérico, que servirá para qualquer tabela.
O procedimento Tabela2DOM() recebe como argumentos o nome do nó raiz, o nome do nó pai, o próprio documento XML e o DataSet. Observe o código abaixo:

procedure TfrmDataXml.Tabela2DOM(Raiz, Registro: string; XMLDoc: TXmlDocument; DataSet: TDataSet);
var
  iRaiz, iPai, iFilho: TDOMNode;
  i, j: Integer;
begin
  DataSet.Open;
  DataSet.First;
  iRaiz := XMLDoc.CreateElement(Raiz);
  XMLDoc.AppendChild(iRaiz);
  j := 0;
  while not DataSet.EOF do
  begin
    iRaiz := XMLDoc.DocumentElement;
    iPai := XMLDoc.CreateElement(Registro);
    iRaiz.AppendChild(iPai);
    for I := 0 to DataSet.FieldCount - 1 do
    begin
      if not (DataSet.Fields[i].IsNull) then
      begin
         iPai := XMLDoc.CreateElement(DataSet.Fields[i].FieldName);
         iFilho := XMLDoc.CreateTextNode(DataSet.Fields[i].AsString);
         iPai.AppendChild(iFilho);
         iRaiz.ChildNodes.Item[j].AppendChild(iPai);
      end;
    end;
    DataSet.Next;
    j := j + 1;
  end;
  DataSet.Close;
end;  

Nas linhas 8 e 9 criamos o nó raiz e o adicionamos ao documento. O método AppendChild() adiciona um nó ao documento.
A partir da linha 11 iniciamos a varredura da tabela. Para cada registro da tabela adicionamos um nó pai com o nome passado como parâmetro, que é feito nas linhas 14 e 15.
O for da linha 16 irá precorrer os campos de cada registro da tabela. Para cada registro criamos um nó pai com o nome do campo (linha 20) e um nó filho com o conteúdo do campo. A linha 18 evita a inclusão de campos vazios no documento.

No evento OnClick do botão criamos o objeto DOM, o procedimento acima é chamado, o documento é gravado usando o método writeXMLFile() e o objeto é destruido.

procedure TfrmDataXml.btnCriarClick(Sender: TObject);
begin
  XMLDoc := TXMLDocument.Create;
  Tabela2DOM ('cidades', 'cidade', XMLDoc, queCidade);
  writeXMLFile(XMLDoc,'cidade.xml');
  XMLdoc.free;
end;   

Para executar lembre de conectar o banco e abrir a tabela, conforme visto em artigos anteriores.
Baixe aqui o código completo do exemplo.

Comentários

Unknown disse…
Por favor, onde consigo as units :

DOM,XMLRead e XMLWrite ?

Obs.: Trabalho com Delphi 7

Desde já agradeço,
Edson Clemente
Professor Carlos disse…
No Delphi tem um componente que faz tudo isso, o XMLDocument. Fica na paleta de componentes Internet. Veja ai se consegue e qualquer dúvida me escreva.
Unknown disse…
Professor, eu já incluir o componente XMLDocument,pois somente as units:
xmldom, XMLIntf, msxmldom, XMLDoc foram acrescentadas no uses, as units DOM e XMLRead e XMLWrite não foram, pois na chama da procedure ReadXMLFile, do seu exemplo, o delphi não as reconhcece.

Agradeço muito a atenção,
Edson Clemente
Professor Carlos disse…
Pra ler use o método LoadFromFile() e pra salvar use SaveToFile(). Ambos são do componente. XMLRead e XMLWrite são apenas do lazarus. Lazarus ainda não tem um componente como Delphi,por isso implementa através dessas três units.
Não tente fazer em Delphi usando o código do meu artigo. Existem algumas diferenças. Veja esse artigo aqui:
http://www.caiooliveira.com.br/?p=73

Postagens mais visitadas deste blog

Lazarus - Acessando banco de dados com SQLdb - Parte I

Para fazer nossa primeira aplicação usando banco de dados no Lazarus vamos usar o SQLite e o conjunto de componentes nativo SQLdb. Inicialmente vamos apresentar passo como essa aplicação foi criada. Essa foi a maneira que eu fiz, e eu agradeço sugestões e questionamentos que pessoas que já passaram por essa experiência. Depois irei fazer algumas considerações sobre o uso do SQLdb. SQLite SQLite é uma biblioteca que implementa um motor de banco de dados SQL. É livre para qualquer finalidade, seja uso particular ou comercial. Lê e escreve em um único arquivo que pode ter além de tabelas, índices, gatilhos e visões. Executa em várias plataformas e é indicado para aplicações embarcadas. Maiores detalhes podem ser encontrados no site oficial. Para usá-lo, baixe-o do site e faça a instalação adequada para o seu sistema operacional. No Windows isso é muito simples, apenas copie sqlite3.dll para o system32 da pasta do sistema operacional. Existe uma ferramenta de linha de comando chamada

Tipos de dados no SQLite

Em SQLite, diferente de outros motores de banco de dados, o tipo de dado de um valor está associado com o valor propriamente dito, e não com o seu contêiner. É um sistema de tipo dinâmico. Um campo de uma tabela em SQLite pode receber qualquer tipo de dado. Assim, o SQLite simplesmente ignora o tipo informado no comando CREATE TABLE. Então, dizemos que no SQLite existem classes de armazenamento. E essas classes são: NULL - como em qualquer outro banco de dados. INTEGER - inteiro com sinal, armazenado em 1, 2, 3, 4, 6 ou 8 bytes dependendo da grandeza do valor. REAL - valor de ponto flutuante armazenado em 8 bytes. TEXT - uma string armazenada usando UTF-8, UTF-16BE ou UTF-16LE. BLOB - armazena um blob, como indica o nome. Uma coluna INTEGER PRIMARY é uma exceção. Só aceita números inteiros. Qualquer valor em um comando SQL tem uma classe de armazenamento implícita. Durante a execução do comando SQL, o SQLite pode converter valores entre classes numéricas (INTEGER e REAL)

Lazarus - Criando relatórios com FortesReport (Parte I)

Para a criação de relatórios, o Lazarus já trás o componente LazReport, no entanto ele precisa ser instalado no IDE. Para fazer a instalação do pacote, acesse o menu Package -> Open package file (.lpk) . Localize o diretório de instalação do Lazarus e na pasta components abra lazreport e depois source . Abra o pacote lazreport.lpk , clique em Compile e depois em Install . Como já sabemos isso irá recompilar o IDE. Depois de inicializado novamente estará disponível a aba LazReport . Leia aqui um tutorial básico sobre o LazReport. No entanto queremos mostrar uma alternativa ao LazReport . Por essa razão, vamos apresentar neste artigo o FortesReport . Para quem conhece o QuickReport, que fazia parte do Delphi, não terá dificuldade de desenvolver com esse componente. Baixe o pacote aqui e instale. Os procedimentos são semelhantes aos que mostramos acima. Você terá uma nova aba chamada Fortes Report . Conectando o banco de dados O primeiro passo para criar a aplicação é fazer