VB .NET - Lendo arquivos XML


Este artigo demonstra como usar a classe XMLTextReader para ler um arquivo XML.A classe XMLTextReader é uma classe abstrata que fornece o acesso rápido a arquivos XML.

Nota: Basicamente podemos ler um arquivo XML usando XmlTextReader, XmlDocument e Xpath;

Se pensarmos que um arquivo XML é um arquivo que pode variar muito de conteúdo, do mais simples ao mais complexo, vamos concluir que ler um arquivo XML pode ser uma tarefa simples ou complexa dependendo do arquivo XML que desejamos ler, de quais informações do arquivo desejamos obter e do que desejamos fazer com a informação extraída do arquivo.

Pensando nisso este artigo se propõe a uma tarefa bem modesta: ler o conteúdo de arquivos XML exibindo os valores dos elementos (somente o texto dos elementos e de seus atributos) usando uma aplicação Windows Forms.

A idéia básica é usar a classe XMLTextReader para ler e percorrer o arquivo XML e inspecionar cada nó do arquivo verificando qual o seu tipo para podermos decidir qual informação desejamos exibir.

Se pensarmos em um documento XML como uma hierarquia de nós podemos encontrar os seguintes tipos de nós e de seus nós filhos em um documento XML:

Tipo de Nó Descrição Nós Filhos possíveis
Document Representa o documento XML Element (max. one), ProcessingInstruction, Comment, DocumentType
DocumentFragment Representa um documento uma porção do documento. Element, ProcessingInstruction, Comment, Text, CDATASection, EntityReference
DocumentType Fornece uma interface para as entidades definidas para o documento. Nenhum
ProcessingInstruction Representa uma instrução de processamento. Nenhum
EntityReference Representa uma referencia de entidade Element, ProcessingInstruction, Comment, Text, CDATASection, EntityReference
Element Representa um elemento Element, Text, Comment, ProcessingInstruction, CDATASection, EntityReference
Attr Representa um atributo. Text, EntityReference
Text Representa um conteúdo textual em um elemento ou atributo. Nenhum
CDATASection Representa uma seção CDATA Nenhum
Comment Representa um comentário Nenhum
Entity Representa uma entidade Element, ProcessingInstruction, Comment, Text, CDATASection, EntityReference
Notation Representa uma notação declarada em um DTD Nenhum
Whitespace Espaço em branco entre a marcação. Nenhum
EndElement Nós EndElement são retornados ao final de um elemento. Nenhum
XmlDeclaration O nó XmlDeclaration deve ser o primeiro nó no documento.Ele não pode ter filhos.Ele é um filho do nó Document
Ele pode ter atributos que provém versão e a codificação de informações.
Nenhum
Notation Um nó de Notation não pode ter nenhum nó filho.Ele poderá aparecer como o filho do nó DocumentType Nenhum

Com base nisso uma das maneiras de obtermos informação de um arquivo XML é ler sequencialmente o arquivo e identifica qual o tipo de Nó e Nó filho o elemento possui extraindo a informação desejada.

Para inspecionar os nós usamos a enumeração NodeType que determina qual o tipo de Nó podendo obter o nome do Nó (elementos/atributos) usando a propriedade Name e o seu valor através da propriedade Value.

Para inspecionar os atributos de um nó podemos usar a propriedade HasAttributes para verificar se o Nó tem algum atributo e o método MoveToNextAttribute para mover-se sequencialmente através de cada atributo do elemento.

Para exemplificar vou mostrar como acessar e ler os valores dos elementos e atributos do arquivo XML livros.xml que possui a seguinte estrutura exibida no navegador IE:

Nota: este arquivo foi obtido do exemplo do artigo da MSDN.

Vamos criar uma aplicação Windows Forms no Visual Basic 2010 Express Edition com o nome lendoArquivoXML;

A seguir inclua no formulário padrão form1.vb os controles Label,TextBox., Button e ListBox conforme o leiaute abaixo:

No evento Click do botão de comando - Obter informações do arquivo XML - inclua o código abaixo:

 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim reader As XmlTextReader = New XmlTextReader(txtCaminhoXML.Text)
        Dim elementos As ArrayList = New ArrayList

        Do While (reader.Read())
            Select Case reader.NodeType
                Case XmlNodeType.Element
                    If reader.HasAttributes Then 'Se existirem atributos
                        While reader.MoveToNextAttribute()
                            'Pega o valor do atributo.
                            elementos.Add(reader.Value)
                        End While
                    End If
                Case XmlNodeType.Text
                    'Incluir o texto do elemento no ArrayList
                    elementos.Add(reader.Value)
            End Select
        Loop

        Dim num As String
        For Each num In elementos
            ListBox1.Items.Add(num)
        Next
    End Sub

Este código irá percorrer o arquivo XML sequencialmente sendo as informações e exibindo-as no controle ListBox:

Lendo tags especificas de um arquivo XML

Se você precisar ler tags específicas de um arquivo XML pode usar a classe XmlDocument que representa um documento XML.

Esta classe possui dezenas de métodos, propriedades e eventos que podemos usar para esmiuçar um arquivo XML.

Vamos tomar como exemplo o arquivo Alunos.xml exibido na figura abaixo:

Se você precisar ler tags específicas deste artigo pode usar o XmlDocument que indica para extrair dados de uma forma não sequencial.

Para realizar esta tarefa vamos usar os seguinte métodos/propriedades:

Agora vamos por a mão na massa...

Vamos ler todas as tags(Nós) do arquivo xml Alunos.xml exibindo os seus valores em um controle ListBox.

Para isso inclua um novo formulário Windows Forms no projeto e defina o mesmo leiaute do formulário anterior:

Agora inclua no evento Click do botão de comando o seguinte código:

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        'Cria uma instância de um documento XML
        Dim oXML As New XmlDocument

        'Define o caminho do arquivo XML 
        Dim ArquivoXML As String = txtNomeArquivo.Text
        'carrega o arquivo XML
        oXML.Load(ArquivoXML)

        'Lê o filho de um Nó Pai específico 
        Dim nomeAluno As String = oXML.SelectSingleNode("Alunos").ChildNodes(0).InnerText
        Dim idadeAluno As String = oXML.SelectSingleNode("Alunos").ChildNodes(1).InnerText
        Dim emailAluno As String = oXML.SelectSingleNode("Alunos").ChildNodes(2).InnerText

        '*** Exibe Dados do aluno
        lstDados.Items.Add(nomeAluno)
        lstDados.Items.Add(idadeAluno)
        lstDados.Items.Add(emailAluno)

        'endereco do aluno
        For i = 0 To 4
            lstDados.Items.Add(oXML.SelectSingleNode("Alunos").ChildNodes(3).ChildNodes(i).InnerText)
        Next

    End Sub

Neste código estamos lendo Nós específicos do arquivo XML usando o método SelectSingleNode(Nome_do_No) e as propriedades ChildNodes e InnerText;

Dim nomeAluno As String = oXML.SelectSingleNode("Alunos").ChildNodes(0).InnerText

- Nesta linha de código estamos lendo o primeiro Nó filho do Nó Alunos e obtendo o seu valor com a propriedade Innertext.

Executando o projeto iremos obter:

Estamos usando um laço for/next para percorrer o Nó Alunos e obter informações do Nó filho Endereco para isso usamos o código abaixo:

For i = 0 To 4
     lstDados.Items.Add(oXML.SelectSingleNode("Alunos").ChildNodes(3).ChildNodes(i).InnerText)
Next

Para entender como esta sendo feita a leitura devemos pensar no arquivo XML com uma estrutura hierárquica onde o Nó Alunos é o nó Pai e o Nó Endereço um Nó filho que possui sub-nós. Assim o índice 3 representa o nó Endereco e o índice 0 o sub-nó Rua , assim por diante. Por isso o código usa : .ChildNodes(3).ChildNodes(i)

Vamos agora incluir um atributo no Nó Endereço para indicar o tipo de endereço igual a residencial. O arquivo Alunos.xml deverá ficar com o seguinte conteúdo:

O código do evento CLick do botão de comando Ler XML segue abaixo:

 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        'Cria uma instância de um documento XML
        Dim oXML As New XmlDocument
        Dim oNoLista As XmlNodeList
        Dim oNo As XmlNode

        'Define o caminho do arquivo XML 
        Dim ArquivoXML As String = txtNomeArquivo.Text
        'carrega o arquivo XML
        oXML.Load(ArquivoXML)

        'Lê o filho de um Nó Pai específico 
        Dim nomeAluno As String = oXML.SelectSingleNode("Alunos").ChildNodes(0).InnerText
        Dim idadeAluno As String = oXML.SelectSingleNode("Alunos").ChildNodes(1).InnerText
        Dim emailAluno As String = oXML.SelectSingleNode("Alunos").ChildNodes(2).InnerText

        '*** Exibe Dados do aluno
        lstDados.Items.Add(nomeAluno)
        lstDados.Items.Add(idadeAluno)
        lstDados.Items.Add(emailAluno)

         ' Define o nó para nova leitura
        oNoLista = oXML.SelectNodes("/Alunos/Endereco")

        'percorre os nós filhos do Nó especificaod e obtem o atributo e os valores
        For Each oNo In oNoLista
            lstDados.Items.Add(oNo.Attributes.GetNamedItem("tipo").Value)
            lstDados.Items.Add(oNo.ChildNodes.Item(0).InnerText)
            lstDados.Items.Add(oNo.ChildNodes.Item(1).InnerText)
            lstDados.Items.Add(oNo.ChildNodes.Item(2).InnerText)
            lstDados.Items.Add(oNo.ChildNodes.Item(3).InnerText)
            lstDados.Items.Add(oNo.ChildNodes.Item(4).InnerText)
        Next

    End Sub

O resultado obtido na execução deste código é o mesmo que o obtido anteriormente com exceção do atributo que esta sendo lido.

Estamos fazendo o mesmo serviço de outra forma usando o método SelectNodes() que seleciona uma lista de Nós definido na expressão. No nosso exemplo estamos selecionando o nó  /Alunos/Endereco;

Em seguida estamos percorrendo o Nó e para obter o valor do atributo "residencial" usamos o método getNamedItem para obter o nome definido do atributo.

oNo.Attributes.GetNamedItem("tipo").Value

Os demais valores são obtidos através do método Item a partir de um nó filho - ChildNodes onde o código oNo.ChildNodes.Item(0).InnerText obtém o valor do Nó filho.

O resultado pode ser visto na figura abaixo onde vemos o valor do atributo sendo exibido:

Existem outra maneiras de extrair informações de um arquivo XML mas isso é assunto para outro artigo.
Pegue o projeto completo aqui:  LendoArquivosXML.zip
Eu sei é apenas VB .NET e XML mas eu gosto...
Simples, simples assim...
Referências:

José Carlos Macoratti