Pular para o conteúdo principal

Lazarus - Lendo XML em um TreeView

XML (Extensible Markup Language) é uma linguagem de marcação, baseada em texto, recomendada pela W3C para troca de informações entre diferentes sistemas e plataformas. Linguagens usadas para troca de dados, como XHTML, a maioria dos WebServices, se baseiam em XML. Aqui está o exemplo de um arquivo XML:


  
    Joao da Silva
    (93)3522-0001
  
  
    Jose Sousa
    (93)3522-0002
    jose@email.com.br
  
  
    Maria da Silva
    (93)3522-0003
    (93)9122-0001
  
  
    Raimunda de Sousa
    rsousa@email.com.br
  


Em Lazarus/Free Pascal existem três units que dão suporte a XML. São chamadas XMLRead, XMLWrite e DOM. Fazem parte da FCL (Biblioteca de Componentes Livres). Só precisamos adicionar as units na cláusula uses para ter suporte a XML.
DOM (Modelo Objeto de Documento) define uma interface padrão. Quando você escreve código que usa essa interface, você pode mudar para outras implementações de DOM sem precisar mudar seu código fonte.

Lendo XML em um TreeView

Como XML tem uma estrutura de árvore, carregar um documento XML em um TTreeView parece bem natural. No nosso exemplo nós carregamos um documento XML em um DOM e depois mostramos a estrutura em um TTreeView. Para mostrar o documento em uma árvore usamos um método recursivo que navega pelos nós e subnós do XML.
Vamos iniciar uma nova aplicação e na cláusula uses da unit vamos adicionar DOM e XMLRead. No form coloque um TEdit, defina Name como edArquivo e delete o conteúdo de Text. Coloque um botão e defina Name como btnAbrir e Caption como Abrir. Insira mais um botão e em Name informe btnLer e em Caption informe Ler. A propriedade Enabled desse botão deve ficar em False. Agora coloque um TTreeView - da aba Common Controls - e em Name digite tvwXML. Coloque também um TOpenDialog da aba Dialogs e mude Name para dlgAbrir. Sua interface irá ficar assim:


No método do evento OnClick do botão btnAbrir escreva o seguinte código:

if dlgAbrir.Execute then
begin
  edArquivo.Text := dlgAbrir.FileName;
  btnLer.Enabled := True;
end;

Esse código abre a caixa de diálogo para selecionar o arquivo XML, atribui o nome do arquivo ao TEdit e habilita o botão btnLer. No botão btnLer vamos executar o código que povoa o TTreeView com os dados do documento XML. O método recursivo será construido separado:

procedure TfrmXml.DomToTree(XmlNode: TDOMNode; TreeNode: TTreeNode);
var
  I: integer;
  NewTreeNode: TTreeNode;
  NodeText: string;
  AttrNode: TDOMNode;
begin
  // considera apenas nós elementos
  if XmlNode.NodeType <> ELEMENT_NODE then
    Exit;
  // inclui o nó
  NodeText := XmlNode.NodeName;
  if (XmlNode.ChildNodes.Count = 1) and (XmlNode.ChildNodes[0].NodeValue <> '')  then
    NodeText := NodeText + ' = ' + XmlNode.ChildNodes[0].NodeValue;
  NewTreeNode := tvwXML.Items.AddChild(TreeNode, NodeText);
  // inclui atributos, se existirem
  for I := 0 to xmlNode.Attributes.Length - 1 do
  begin
    AttrNode := xmlNode.Attributes.Item[I];
    tvwXML.Items.AddChild(NewTreeNode,
      '[' + AttrNode.NodeName + ' = "' + AttrNode.NodeValue + '"]');
  end;
  // inclui cada nó filho
  if XmlNode.HasChildNodes then
    for I := 0 to xmlNode.ChildNodes.Count - 1 do
      DomToTree(xmlNode.ChildNodes.Item[I], NewTreeNode);
end;

Este método utiliza várias operações que podemos fazer com DOM. Cada nó tem uma propriedade denominada NodeType, para determinar se é um elemento, atributo, nó texto, etc (linha 09). Nas linhas 13 e 14 podemos observar que NodeValue - a representação textual - só pode ser acessado se o nó tiver um elemento textual. Após mostrar o nome do item e o valor textual - se houver - o método mostra o conteúdo de cada atributo. Em seguida chamamos o método recursivamente para mostrar cada subnó.
A interface do método deve ser informada na seção type. O método do evento OnClick do botão btnLer deve ser assim:

procedure TfrmXml.btnLerClick(Sender: TObject);
var
  Documento: TXMLDocument;
begin
  tvwXML.Items.Clear;
  ReadXMLFile(Documento, edArquivo.Text);
  DomToTree(Documento.DocumentElement, nil);
  tvwXML.FullExpand;
  Documento.Free;
end;

Ele cria um DOM a partir do arquivo XML e depois chama o método que povoa o TTreeView.
Faça o download do código fonte do exemplo aqui.

Atualizado em 08/04/2010.

Comentários

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