Você está na página 1de 10

VB 6 - Integrando XML com VB

No artigo - XML - eXtensible Markup Language - Introduo - abordei os conceitos


bsicos 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 servio . Como voc
no vai querer reinventar a roda no mesmo, creio que a segunda opo esta de bom
tamanho.

Um interpretador para ler arquivos XML conhecido como um XML Parser , e, existem muitos
programas que cumprem esta funo . 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 memria para representar os dados do arquivo XML permitindo acessar de forma aleatria
qualquer n dentro do documento XML.

O XML DOM tambm 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 aplicao Visual Basic navegar atravs da rvore com ns representando elementos ,
atributos , comentrios e outras estruturas. Abaixo do nvel do n raiz ( o topo ) temos os ns
filhos , parentes e irmos interligados ou no.

A API XML DOM permite o modelo de objeto representar um n e obter informaes sobre
um n e os demais ns a ele ligados . A interface Node (n) o corao do esquema DOM ;
praticamente tudo que precisamos para obter as informaes em um arquivo XML. Abaixo
temos uma representao desta interface e os principais tipos de ns.

Tipo de N Valor Descrio


NODE_ELEMENT 1 Representa um elemento
NODE_ATTRIBUTE 2 Representa um atributo de um elemento
NODE_TEXT 3 Representa uma tag com texto
NODE_PROCESSING_INSTRUCTION 7 Representa uma instruo e processamento de um docmento XML
NODE_COMMENT 8 Representa um comentrio
NODE_DOCUMENT 9 Reresenta um objeto documento
NODE_DOCUMENT_TYPE 10 Representa a declarao do tipo de documento indicado pela tag - <IDOCTYPE>

Ento resumindo :

Cada objeto implementado via API DOM um N ( Node )


O objeto DOMDocument contm o documento XML.
A partir do DOMDocument acessamos os dados XML atravs da propriedade -
documentElement - que esta disponvel a partir da interface IXMLDOMElement ou
IXMLDOMNode
Essas interfaces possuem a propriedade - childNodes - a partir da qual interamos
atravs de cada elemento - child , comentrio , etc.. do N Pai.
A interface - IXMLDOMNodeList - permite o acesso a coleo de Ns ( Nodes) como
filhas de um elemento.

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 referncia 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 ) >
Ento vamos ter que ler os dados do arquivo agenda.xml e exibir em um formulrio Visual
Basic. J vou adiantando o layout do formulrio . O jeito dele dado abaixo:
A idia a seguinte:

- Vou ler e exibir os


dados do arquivo
agenda.xml em um
controle Treeview

- Quando o usurio
clicar em um N os
dados sero exibidos
nas caixas de texto
do formulrio

- Vou dar a opo do


usurio ver o
arquivo XML usando
um controle
WebBrowser para
exibir os dados do
arquivo agenda.xml

- Darei tambm a
opo de poder
incluir/excluir um
elemento no arquivo
agenda.xml e trat-
lo como sendo um
novo dado

Quando o usurio
clicar no
boto :Preenche os
dados do arquivo
agenda.xml sero
exibidos como na
figura ao lado.

- Ao clicar em um
N (sinal de +) os
dados sero exibidos
nas caixas de texto

Agora vamos ao cdigo do projeto:

1- Inicie um novo projeto no Visual Basic e faa as seguintes referncias no mesmo:

Microsoft Internet Controls - (WebBrowser)


Microsoft XML 2.0/3.0 - (API XML DOM)
Microsoft Windows Common Controls 6.0 - (TreeView)
2- Cdigo da seo General Declarations : Declara as variveis visveis no formulrio.

Option Explicit
Private m_objDOMPessoa As DOMDocument
Private m_blnItemClicked As Boolean
Private m_strXmlPath As String
Dim flagpreenche As Boolean
3- Cdigo do evento Load do formulrio: definimos o caminho do arquivo agenda.xml e
atribuimos o valor False a varivel - flagpreenche.

Private Sub Form_Load()


m_strXmlPath = App.Path & "\agenda.xml"
flagpreenche = False
End Sub

4- Agora temos o cdigo do boto - 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 contedo do arquivo xml
webTarget.Navigate m_strXmlPath
cmdExcluir.Enabled = True
cmdIncluir.Enabled = True

End Sub

O cdigo acima invoca o procedimento - PreencherTreeWithChildren - para preencher


TreeView com os elementtos. O cdigo 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 ns


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 atravs dos Ns 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 usurio clica em um N ele se expande e exibe os detalhes no controle TreeView e
nas caixas de texto. O cdigo 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 contedo do arquivo XML , basta clicar no boto - XML >> . O controle
WebBrowser exibe os dados do arquivo xml conforme abaixo:( O cdigo esta ao lado)

Private Sub Cmdxml_Click()


If cmdxml.Caption = "XML >>" T
Me.Height = 7200
webTarget.Visible = True
cmdxml.Caption = "<< XML"
ElseIf cmdxml.Caption="<<XML"
Me.Height = 4215
webTarget.Visible = False
cmdxml.Caption = "XML >>"
End If
End Sub

- Codigo para exibir os dados

do arquivo agenda.xml no contr

webbrowser.

- Os cdigo 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 boto - Incluir - podemos incluir um novo elemento no arquivo agenda.xml . O


cdigo associado ao evento click do boto 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 cdigo associado ao evento Click do boto - Salvar

Private Sub cmdSalvar_Click()


salvarNovaPessoa
cmdAdd.Enabled = False
End Sub

- Este cdigo chama a procedure - salvarNovaPessoa cujo cdigo :

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 cdigo associado ao evento Click do boto -
Excluir:

Private Sub cmdExcluir_Click()


deleteSelectedPerson tvwPessoa.SelectedItem
End Sub

- O cdigo acima chama a funo - deleteSelectedPerson - que tem o seu cdigo 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 so exibidos o codigo ID do elemento exibido atravs seguinte cdigo :

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 cdigo do projeto aqui : vbxml.zip - ( 6 KB )