Desenvolvimento - XML
VB: Usando XML para pequenas base de dados
É inquestionável a importância dos bancos de dados de alto desempenho como os SQLs, ORACLE e até mesmo o ACCESS no desenvolvimento de aplicativos, mas há alguns momentos em que o uso de ferramentas tão sofisticadas parece não ter sentido.
por Marco Aurélio BarbieroUm caso emblemático foi o de um aplicativo para impressão de envelopes que avaliei e que tinha como única tarefa armazenar meia dúzia de endereços e depois imprimi-los em envelopes. O desenvolvedor agregou bases ACCESS e objetos para gerenciar estas bases que acabaram produzindo um instalador de 6 MB. A mesma aplicação usando base de dados em XML ficou muito mais simples e legível.
De qualquer forma, independente da utilidade, o assunto é muito interessante, especialmente para "fuçadores".
Neste arquivo, essencialmente prático, vamos desenvolver algumas rotinas para utilizar arquivos XML em substituição aos clássicos arquivos ".INI": basicamente ler e gravar informações de configuração.
No VB6 que uso para desenvolver é necessário um passo preliminar para agregar suporte ao XML:
Eu usei a versão 3.0 do Microsoft XML, mas acredito que a versão 2.0 já seja suficiente.
Inicialmente o arquivo XML pode ser simples, contendo apenas configurações em nós filhos do nóraiz:
É possível criar diferentes seções para Impressão, Cores, Margens, etc, mas não vamos fazer isso neste tutorial.
Nossa primeira tarefa é muito simples: carregar o arquivo XML no objeto objDOC ou criar o arquivo, se não existir.
Private Sub AbreDocXML(nmArquivo) " Se arquivo não existe, cria; caso contrário, carrega o XML If Not objDoc.Load(Environ("CommonProgramFiles") & "\" & nmArquivo) Then Set NodeCONFIG = objDoc.createNode(NODE_ELEMENT, "CONFIG", "") objDoc.appendChild objXMLDomNode objDoc.save (Environ("CommonProgramFiles") & "\" & nmArquivo) Else Set NodeCONFIG = objDoc.documentElement End If End Sub
O objeto "objDoc" é a base de qualquer aplicativo que use XML e DOM: os nós filhos são criados usando este objeto e depois anexados ao nível hierárquico desejado.
A procedure "AbreDocXML" tenta abrir o arquivo nmArquivo e carregar seu conteúdo no " objDOC" . Diante da impossibilidade de carregar os dados, um nó é criado com o nome " nodeCONFIG" . Este nó será o nó raiz do documento XML. O nodeCONFIG é anexado ao objDOC e o arquivo é salvo na pasta especificada, geralmente "Arquivos de Programas".
Se o arquivo for localizado e não houver erro na carga o objeto nodeCONFIG é definido como nó raiz pela instrução " set nodeCONFIG = objDOC.documentElement" .
Embora seja possível trabalhar com o nó raiz usando uma referência a " objDOC.documentElement" a definição de um objeto com o nome da TAG do nó raiz melhora muito a legibilidade.
Obs. é meu costume criar objetos para os níveis hierárquicos mais próximos da raiz e nomeá-los com o nome da TAG. Adicionalmente, crio um objeto genérico (objXML) para as operações de recuperação e gravação de dados.
A instrução " objDoc.save ..." grava o documento em um arquivo.
Uma vez carregado ou criado o arquivo, o trabalho de definição ou recuperação dos valores será feito pelas funções " defineConfig" e " obtemConfig" . As duas funções recebem como parâmetros o nome do arquivo e da TAG a ser definida ou recuperada. No caso de " defineConfig" deve ser passado, também, o novo valor para o parâmetro.
Começando com "defineConfig"
Public Sub defineConfig(nmArquivo, parametro, valor) AbreDocXML (nmArquivo) Set NodeCONFIG = objDoc.documentElement Set nodeXML = NodeCONFIG.selectSingleNode(parametro) " Se o parâmetro não existe ele é criado, caso contrário apenas define o valor If nodeXML Is Nothing Then Set nodeXML = objDoc.createNode(NODE_ELEMENT, parametro, "") NodeCONFIG.appendChild nodeXML End If nodeXML.Text = valor " Grava o documento XML objDoc.save (Environ("CommonProgramFiles") & "\" & nmArquivo) " Limpando a área Set NodeCONFIG = Nothing Set nodeXML = Nothing End Sub
As primeiras linhas se encarregam de abrir o arquivo e definir o elemento raiz (documentElement) que passa a ser referenciado como " nodeConfig" .
O método " selectSingleNode" retorna um único nó a partir do parâmetro. No nosso caso, como temos apenas dois níveis hierárquicos, este parâmetro é muito simples, resumindo-se ao nome da TAG. É possível usar " selectSingleNode" para selecionar nós em uma hierarquia complexa usando todo o caminho (" impressora/margens/direita" ) ou a partir de valores das TAGs ou atributos.
Se a TAG não existir ela é criada e anexada ao nó-raiz.
Obs: Lembre-se que em XML maiúsculas e minúsculas são diferentes.
O atributo " Text" é definido com o valor passado para a função.
Os dados são gravados no arquivo e os objetos eliminados.
A função obtemConfig
Public Function obtemConfig(nmArquivo, parametro) AbreDocXML (nmArquivo) Set NodeCONFIG = objDoc.documentElement Set nodeXML = NodeRaiz.selectSingleNode(parametro) " Se o parâmetro não existe retorna vazio, caso contrário retorna o valor If nodeXML Is Nothing Then obtemConfig = "" Else obtemConfig = nodeXML.Text End If " Limpando a área Set NodeCONFIG = Nothing Set nodeXML = Nothing End Function
Esta função é ainda mais simples que " defineConfig" , limita-se a verificar a existência de um parâmetro e retornar o valor definido na TAG. Como não é uma aplicação crítica, no caso de não encontrar o caminho a função simplesmente retorna um valor vazio.
Considerações finais
Para testar as funções eu criei um forma com duas caixas de texto (" txtParametro" e " txtValor" ) e dois botões (" cmdDefine" e " cmdObtem" ).
Apesar de sua simplicidade, acredito que este artigo será de grande valor para os iniciantes, principalmente para aqueles que gostam de ver os resultados práticos desde o início. Nos próximos artigos vamos criar bases de dados mais complexas.
Um abraço,
Marco Aurélio Barbiero