No artigo - XML - eXtensible Markup Language - Introdução - abordei os conceitos básicos sobre XML ; no artigo Usando XSL - Extensible Style Language - mostrei como trabalhar com XLS para exibir arquivos XML em um navegador. Muito bem ! E se você precisar acessar um arquivo XML a partir do Visual Basic ? Este é o assunto deste artigo.
Para acessar um arquivo XML usando o Visual Basic você pode escolher : criar você mesmo um programa para fazer a leitura ou usar um programa já pronto para fazer o serviço . Como você não vai querer reinventar a roda não é mesmo, creio que a segunda opção esta de bom tamanho.
Um interpretador para ler arquivos XML é conhecido como um XML Parser , e, existem muitos programas que cumprem esta função . Neste artigo eu vou falar sobre o XML DOM ( Document Object Model).
O XML DOM utiliza o modelo Tree-Based (baseado em árvore) e cria uma estrutura de dados na memória para representar os dados do arquivo XML permitindo acessar de forma aleatória qualquer nó dentro do documento XML.
O XML DOM também representa um modelo de objeto a partir do qual podemos interpretar e criar dados ; como este modelo é um modelo baseado em árvore o modelo DOM vai permitir a nossa aplicação Visual Basic navegar através da árvore com nós representando elementos , atributos , comentários e outras estruturas. Abaixo do nível do nó raiz ( o topo ) temos os nós filhos , parentes e irmãos interligados ou não.
A API XML DOM permite o modelo de objeto representar um nó e obter informações sobre um nó e os demais nós a ele ligados . A interface Node (nó) é o coração do esquema DOM ; é praticamente tudo que precisamos para obter as informações em um arquivo XML. Abaixo temos uma representação desta interface e os principais tipos de nós.
|
Então resumindo :
A hierarquia das interfaces presente no modelo DOM esta representado abaixo. (somente as interfaces mais comuns). |
O parser XML usado no Visual Basic é o MXSML - (http://msdn.microsoft.com/xml) e é ele que vamos usar neste artigo.
Lendo e exibindo os dados de um arquivo XML
Nosso objetivo será ler e exibir os dados de um arquivo xml em um programa Visual Basic . Como exemplos eu peguei um arquivo xml qualquer chamado agenda.xml. Este arquivo possui a seguinte estrutura :
<?xml version="1.0"?> <!-- *********** agenda para pessoas *********** --> <!DOCTYPE PEOPLE SYSTEM "agenda.dtd"> <PEOPLE> <PERSON PERSONID="p1"> <NAME>Mark Wilson</NAME> <ADDRESS>911 Somewhere Circle, Canberra, Australia</ADDRESS> <TEL>(++612) 12345</TEL> <FAX>(++612) 12345</FAX> <EMAIL>markwilson@somewhere.com</EMAIL> </PERSON> <PERSON PERSONID="p2"> <NAME>Tracey Wilson</NAME> <ADDRESS>121 Zootle Road, Cape Town, South Africa</ADDRESS> <TEL>(++2721) 531 9090</TEL> <FAX>(++2721) 531 9090</FAX> <EMAIL>Tracey Wilson@somewhere.com</EMAIL> </PERSON> <PERSON PERSONID="p3"> <NAME>Jodie Foster</NAME> <ADDRESS>30 Animal Road, New York, USA</ADDRESS> <TEL>(++1) 3000 12345</TEL> <FAX>(++1) 3000 12345</FAX> <EMAIL>Jodie Foster@somewhere.com</EMAIL> </PERSON> <PERSON PERSONID="p4"> <NAME>Lorrin Maughan</NAME> <ADDRESS>1143 Winners Lane, London, UK</ADDRESS> <TEL>(++94) 17 12345</TEL> <FAX>++94) 17 12345</FAX> <EMAIL>Lorrin Maughan@somewhere.com</EMAIL> </PERSON> <PERSON PERSONID="p5"> <NAME>Steve Rachel</NAME> <ADDRESS>90210 Beverly Hills, California, USA</ADDRESS> <TEL>(++1) 2000 12345</TEL> <FAX>(++1) 2000 12345</FAX> <EMAIL>Steve Rachel@somewhere.com</EMAIL> </PERSON> <PERSON PERSONID="p6"><NAME>Macoratti</NAME> <ADDRESS>Rua doze , 100</ADDRESS> <FAX>017-2247766</FAX> <TEL>1632-4654</TEL> <EMAIL>macoratti@riopreto.com.br</EMAIL> </PERSON> </PEOPLE> |
Note que o arquivo agenda.xml faz referência ao arquivo agenda.dtd cuja estrutra é a seguinte:
<!ENTITY USA
"United States of America"> <!ENTITY UK "United Kingdom"> <!ELEMENT PEOPLE ( PERSON+ ) > <!ELEMENT PERSON ( NAME, ADDRESS, TEL, FAX, EMAIL ) > <!ATTLIST PERSON PERSONID ID #REQUIRED> <!ELEMENT NAME (#PCDATA)> <!ELEMENT ADDRESS ( #PCDATA ) > <!ELEMENT TEL ( #PCDATA ) > <!ELEMENT FAX ( #PCDATA ) > <!ELEMENT EMAIL ( #PCDATA ) > |
Então vamos ter que ler os dados do arquivo agenda.xml e exibir em um formulário Visual Basic. Já vou adiantando o layout do formulário . O jeitão dele é dado abaixo:
A idéia é a seguinte: - Vou ler e exibir os dados do arquivo agenda.xml em um controle Treeview - Quando o usuário clicar em um Nó os dados serão exibidos nas caixas de texto do formulário - Vou dar a opção do usuário ver o arquivo XML usando um controle WebBrowser para exibir os dados do arquivo agenda.xml - Darei também a opção de poder incluir/excluir um elemento no arquivo agenda.xml e tratá-lo como sendo um novo dado |
Quando o usuário clicar no
botão :Preenche os dados do arquivo agenda.xml
serão exibidos como na figura ao lado. - Ao clicar em um Nó (sinal de +) os dados serão exibidos nas caixas de texto |
Agora vamos ao código do projeto:
1- Inicie um novo projeto no Visual Basic e faça as seguintes referências no mesmo:
2- Código da seção General Declarations : Declara as variáveis visíveis no formulário.
Option Explicit Private m_objDOMPessoa As DOMDocument Private m_blnItemClicked As Boolean Private m_strXmlPath As String Dim flagpreenche As Boolean |
3- Código do evento Load do formulário: definimos o caminho do arquivo agenda.xml e atribuimos o valor False a variável - flagpreenche.
Private Sub Form_Load() m_strXmlPath = App.Path & "\agenda.xml" flagpreenche = False End Sub |
4- Agora temos o código do botão - Preenche - que irá carregar e ler os dados do arquivo agenda.xml e exibí-lo no controle - tvwPessoa.
Private Sub cmdPreencher_Click() Dim objPessoaRoot As IXMLDOMElement Dim objPessoaElement As IXMLDOMElement Dim tvwRoot As Node Dim X As IXMLDOMNodeList flagpreenche = True cmdxml.Enabled = True Set m_objDOMPessoa = New DOMDocument m_objDOMPessoa.resolveExternals = True m_objDOMPessoa.validateOnParse = True 'carrega o XML no documento DOM m_objDOMPessoa.async = False Call m_objDOMPessoa.Load(m_strXmlPath) 'verifica se a carga do XML foi feita com sucesso If m_objDOMPessoa.parseError.reason <> "" Then MsgBox m_objDOMPessoa.parseError.reason Exit Sub End If 'obtem o elemento raiz do XML Set objPessoaRoot = m_objDOMPessoa.documentElement 'define as propriedades do Treeview tvwPessoa.LineStyle = tvwRootLines tvwPessoa.Style = tvwTreelinesPlusMinusText tvwPessoa.Indentation = 400 'verifica se o treeview ja foi preenchido 'se ja foi remove o raiz que remove tudo If tvwPessoa.Nodes.Count > 0 Then tvwPessoa.Nodes.Remove 1 End If ' inclui um nó filho ao nó rai do TreeView Set tvwRoot = tvwPessoa.Nodes.Add() tvwRoot.Text = objPessoaRoot.baseName ' iteracao atraves de cada elemento para encher a arvore que por sua vez interagem atraves de cada childNode do element(objPessoaElement) For Each objPessoaElement In objPessoaRoot.childNodes PreencherTreeWithChildren objPessoaElement Next ' carregamos o controle webbrowser com o conteúdo do arquivo xml webTarget.Navigate m_strXmlPath cmdExcluir.Enabled = True cmdIncluir.Enabled = True End Sub |
O código acima invoca o procedimento - PreencherTreeWithChildren - para preencher TreeView com os elementos. O código é o seguinte:
Private Sub PreencherTreeWithChildren(objDOMNode As IXMLDOMElement) Dim objNameNode As IXMLDOMNode Dim objAttributes As IXMLDOMNamedNodeMap Dim objAttributeNode As IXMLDOMNode Dim objPessoaElement As IXMLDOMElement Dim intIndex As Integer Dim tvwElement As Node Dim tvwChildElement As Node 'obtem o nome do elemento selecionado Set objNameNode = objDOMNode.selectSingleNode("NAME") 'inclui os elementos aos nós Set tvwElement = tvwPessoa.Nodes.Add(1, tvwChild) tvwElement.Text = objNameNode.parentNode.nodeName & ": " _ & objNameNode.nodeTypedValue Set objAttributes = objDOMNode.Attributes 'verifica os atributos If objAttributes.length > 0 Then ' obtendo o item para a referencia ''PERSONID', ' com NameNodeListMap para o Nó atual Set objAttributeNode = objAttributes.getNamedItem("PERSONID") 'armazena o valor na tag do treeview tvwElement.Tag = objAttributeNode.nodeValue End If tvwElement.EnsureVisible intIndex = tvwElement.Index 'interagem através dos Nós filhos(childNodes) do objeto DOMNode ' para preencher o TreeView os seus valores For Each objPessoaElement In objDOMNode.childNodes Set tvwChildElement = tvwPessoa.Nodes.Add(intIndex, tvwChild) tvwChildElement.Text = objPessoaElement.nodeTypedValue Next End Sub |
Quando o usuário clica em um Nó ele se expande e exibe os detalhes no controle TreeView e nas caixas de texto. O código do evento Click do controle treeView - tvwPessoa é o seguinte:
Private Sub tvwPessoa_Click() Dim objSelNode As Node If m_blnItemClicked = True Then m_blnItemClicked = False Exit Sub End If Set objSelNode = tvwPessoa.SelectedItem populatePessoaDetalhes objSelNode End Sub |
Para exibir o conteúdo do arquivo XML , basta clicar no botão - XML >> . O controle WebBrowser exibe os dados do arquivo xml conforme abaixo:( O código esta ao lado)
Private Sub Cmdxml_Click() If cmdxml.Caption = "XML >>" Then Me.Height = 7200 webTarget.Visible = True cmdxml.Caption = "<< XML" ElseIf cmdxml.Caption="<<XML" Then Me.Height = 4215 webTarget.Visible = False cmdxml.Caption = "XML >>" End If End Sub - Codigo para exibir os dados do arquivo agenda.xml no controle webbrowser. |
- Os código para expandir e retrair o Nó selecionado é o seguinte:
Private Sub tvwPessoa_Collapse(ByVal Node As MSComctlLib.Node) populatePessoaDetalhes Node m_blnItemClicked = True End Sub Private Sub tvwPessoa_Expand(ByVal Node As MSComctlLib.Node) populatePessoaDetalhes Node m_blnItemClicked = True End Sub |
- Ao clicar no botão - Incluir - podemos incluir um novo elemento no arquivo agenda.xml . O código associado ao evento click do botão é dado abaixo:
Private Sub cmdIncluir_Click() lblElemento.Caption = "" txtNome.Text = "" txtEndereco.Text = "" txtTel.Text = "" txtFax.Text = "" txtEmail.Text = "" cmdIncluir.Enabled = True End Sub |
- Para salvar um novo elemento usamos o código associado ao evento Click do botão - Salvar
Private Sub cmdSalvar_Click() salvarNovaPessoa cmdAdd.Enabled = False End Sub |
- Este código chama a procedure - salvarNovaPessoa cujo código é :
Private Sub salvarNovaPessoa() 'cria um novo elemento e inclui no objeto dom Dim objPerson As IXMLDOMElement Dim objNewChild As IXMLDOMElement 'cria um novo elemento PERSON Set objPerson = m_objDOMPessoa.createElement("PERSON") objPerson.setAttribute "PERSONID", getNewID m_objDOMPessoa.documentElement.appendChild objPerson 'cria um elmeneto (objPerson), e inclui no No Filho(childNodes) Set objNewChild = m_objDOMPessoa.createElement("NAME") objNewChild.Text = txtName.Text objPerson.appendChild objNewChild Set objNewChild = m_objDOMPessoa.createElement("ADDRESS") objNewChild.Text = txtAddress.Text objPerson.appendChild objNewChild Set objNewChild = m_objDOMPessoa.createElement("TEL") objNewChild.Text = txtTel.Text objPerson.appendChild objNewChild Set objNewChild = m_objDOMPessoa.createElement("FAX") objNewChild.Text = txtFax.Text objPerson.appendChild objNewChild Set objNewChild = m_objDOMPessoa.createElement("EMAIL") objNewChild.Text = txtEmail.Text objPerson.appendChild objNewChild 'sincroniza com o TreeView PreencherTreeWithChildren objPerson m_objDOMPessoa.save m_strXmlPath webTarget.Refresh Set objPerson = Nothing Set objNewChild = Nothing End Sub |
- Para excluir um elemento usamos o seguinte código associado ao evento Click do botão - Excluir:
Private Sub cmdExcluir_Click() deleteSelectedPerson tvwPessoa.SelectedItem End Sub |
- O código acima chama a função - deleteSelectedPerson - que tem o seu código exibido abaixo:
Private Sub populatePessoaDetalhes(objSelNode As Node) ' preenche os textbox dos formulario com os detalhes do documento Dim objPessoaElement As IXMLDOMElement Dim objChildElement As IXMLDOMElement If objSelNode Is Nothing Then Exit Sub 'ignora a selecao do TreeView se nao foi clicado um No "PERSON" If Trim(objSelNode.Tag) <> "" Then 'obtem o no(element type), que possui um atributo ao valor 'da tag do TreeView Set objPessoaElement = m_objDOMPessoa.nodeFromID(objSelNode.Tag) lblElemento.Caption = objPessoaElement.nodeName & ": ID = " & _ objPessoaElement.Attributes(0).nodeValue 'interagem atraves dos nos achadose preenche o texto com os conteudo dos nos For Each objChildElement In objPessoaElement.childNodes 'verifica o tipo de No que estamos tratando If objChildElement.nodeType = NODE_ELEMENT Then Select Case UCase(objChildElement.nodeName) Case "NAME" txtNome.Text = objChildElement.nodeTypedValue Case "ADDRESS" txtEndereco.Text = objChildElement.nodeTypedValue Case "TEL" txtTel.Text = objChildElement.nodeTypedValue Case "FAX" txtFax.Text = objChildElement.nodeTypedValue Case "EMAIL" txtEmail.Text = objChildElement.nodeTypedValue End Select End If Next objChildElement End If Set objChildElement = Nothing Set objPessoaElement = Nothing End Sub |
Quando os dados são exibidos o codigo ID do elemento é exibido através seguinte código :
Private Function getNewID() As String getNewID = "p" & m_objDOMPessoa.documentElement.childNodes.length + 1 End Function |
Com isto acabei de mostrar como tratar arquivos XML no VB usando o DOM ...
Pegue o código do projeto aqui : vbxml.zip - ( 6 KB )
Gostou ? Compartilhe no Facebook Compartilhe no Twitter
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#