XML (C#) - Revisão - Conceitos Básicos - 3


Este é o terceiro e último artigo do resumo dos conceitos básicos sobre XML com C#.

No artigo anterior eu mostrei como podemos ler uma arquivo 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 ideia 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. link: http://msdn.microsoft.com/en-us/library/windows/desktop/ms762271%28v=vs.85%29.aspx)

  <?xml version="1.0"?>
<catalog>
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications with XML.</description>
   </book>
   <book id="bk102">
      <author>Ralls, Kim</author>
      <title>Midnight Rain</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-12-16</publish_date>
      <description>A former architect battles corporate zombies,an evil sorceress, and her own childhood to become queen 
      of the world.</description>
   </book>
   <book id="bk103">
      <author>Corets, Eva</author>
      <title>Maeve Ascendant</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2000-11-17</publish_date>
      <description>After the collapse of a nanotechnology society in England, the young survivors lay the foundation for a new society.</description>
   </book>
   <book id="bk104">
      <author>Corets, Eva</author>
      <title>Oberon's Legacy</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date>2001-03-10</publish_date>
      <description>In post-apocalypse England, the mysterious agent known only as Oberon helps to create a new life for the inhabitants 
of London. Sequel to Maeve Ascendant.</description>
   </book>
</catalog>

Vamos criar uma aplicação Windows Forms no Visual C# 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:

Os namespaces usados no formulário são:

using System;
using System.Collections;
using System.Windows.Forms;
using System.Xml;

Inclua o evento Click do botão de comando o código a seguir:

     private void btnLerXML_Click(object sender, EventArgs e)
        {
            XmlTextReader reader = new XmlTextReader(txtCaminhoXML.Text);
            ArrayList elementos = new ArrayList();

            while ((reader.Read())) {
	            switch (reader.NodeType) {
		            case XmlNodeType.Element:
			            //Se existirem atributos
			            if (reader.HasAttributes) {
				            while (reader.MoveToNextAttribute()) {
					            //Pega o valor do atributo.
					            elementos.Add(reader.Value);
				            }
			            }
			            break;
		            case XmlNodeType.Text:
			            //Incluir o texto do elemento no ArrayList
			            elementos.Add(reader.Value);
			            break;
	            }
            }
            foreach ( var num in elementos) {
	            lstXML.Items.Add(num);
            }
        }

Executando o projeto iremos obter o resultado abaixo onde vemos as informações das tags XML sendo exibidas:

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:

<?xml version="1.0"?>
<Alunos>
   <nome>Jose Carlos Macoratti</nome>
   <idade>48</idade>
   <email>macoratti@yahoo.com</email>
   <Endereco>
      <Rua>Projetada 100</Rua>
  <Bairro>Centro</Bairro>
  <Cidade>Lins</Cidade>
  <Estado>SP</Estado>
  <Cep>16520-005</Cep>
   </Endereco>
</Alunos>

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 controle Button(btnLerTags) no formulário Windows Forms do projeto e definir o seguinte código no seu evento Click:

   private void btnLerTag_Click(object sender, EventArgs e)
        {

            //Cria uma instância de um documento XML
                XmlDocument oXML = new XmlDocument();

                //Define o caminho do arquivo XML 
                string ArquivoXML = txtCaminhoXML.Text;
                //carrega o arquivo XML
                oXML.Load(ArquivoXML);

                //Lê o filho de um Nó Pai específico 
                string nomeAluno = oXML.SelectSingleNode("Alunos").ChildNodes[0].InnerText;
                string idadeAluno = oXML.SelectSingleNode("Alunos").ChildNodes[1].InnerText;
                string emailAluno = oXML.SelectSingleNode("Alunos").ChildNodes[2].InnerText;

                //*** Exibe Dados do aluno
                lstXML.Items.Add(nomeAluno);
                lstXML.Items.Add(idadeAluno);
                lstXML.Items.Add(emailAluno);

                //endereco do aluno
                for (int i = 0; i <= 4; i++)
                {
                    lstXML.Items.Add(oXML.SelectSingleNode("Alunos").ChildNodes[3].ChildNodes[i].InnerText);
                }
        }

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:

       'endereco do aluno
        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:

Para ler o conteúdo do arquivo XML, altere o código do evento CLick do botão de comando conforme abaixo:

           private void btnLerTag_Click(object sender, EventArgs e)
        {
                //Cria uma instância de um documento XML
	      XmlDocument oXML = new XmlDocument();
	      XmlNodeList oNoLista = default(XmlNodeList);

                //Define o caminho do arquivo XML 
                string ArquivoXML = txtCaminhoXML.Text;
                //carrega o arquivo XML
                oXML.Load(ArquivoXML);

                //Lê o filho de um Nó Pai específico 
                string nomeAluno = oXML.SelectSingleNode("Alunos").ChildNodes[0].InnerText;
                string idadeAluno = oXML.SelectSingleNode("Alunos").ChildNodes[1].InnerText;
                string emailAluno = oXML.SelectSingleNode("Alunos").ChildNodes[2].InnerText;

                //*** Exibe Dados do aluno
                lstXML.Items.Add(nomeAluno);
                lstXML.Items.Add(idadeAluno);
                lstXML.Items.Add(emailAluno);

                ////endereco do aluno
                //for (int i = 0; i <= 4; i++)
                //{
                //    lstXML.Items.Add(oXML.SelectSingleNode("Alunos").ChildNodes[3].ChildNodes[i].InnerText);
                //}
                //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
            foreach (XmlNode oNo in oNoLista) {
        	            lstXML.Items.Add(oNo.Attributes.GetNamedItem("tipo").Value);
    	            lstXML.Items.Add(oNo.ChildNodes.Item(0).InnerText);
                	    lstXML.Items.Add(oNo.ChildNodes.Item(1).InnerText);
	            lstXML.Items.Add(oNo.ChildNodes.Item(2).InnerText);
	            lstXML.Items.Add(oNo.ChildNodes.Item(3).InnerText);
	            lstXML.Items.Add(oNo.ChildNodes.Item(4).InnerText);
                }
        }

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: CriandoXML.zip

Salmos 14:1 Diz o néscio no seu coração: Não há Deus. Os homens têm-se corrompido, fazem-se abomináveis em suas obras; não há quem faça o bem.

Salmos 14:2 O Senhor olhou do céu para os filhos dos homens, para ver se havia algum que tivesse entendimento, que buscasse a Deus.

Salmos 14:3 Desviaram-se todos e juntamente se fizeram imundos; não há quem faça o bem, não há sequer um.

Salmos 14:4 Acaso não tem conhecimento nem sequer um dos que praticam a iniqüidade, que comem o meu povo como se comessem pão, e que não invocam o Senhor?

Salmos 14:5 Achar-se-ão ali em grande pavor, porque Deus está na geração dos justos.

Salmos 14:6 Vós quereis frustar o conselho dos pobres, mas o Senhor é o seu refúgio.

Salmos 14:7 Oxalá que de Sião viesse a salvação de Israel! Quando o Senhor fizer voltar os cativos do seu povo, então se regozijará Jacó e se alegrará Israel.


Veja os Destaques e novidades do SUPER CD VB 2012 (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Veja mais sistemas completos para a plataforma .NET no Super CD .NET e no Super DVD .NET , confira...

Quer aprender C# ??

Chegou o Super DVD C# 2012 com exclusivo material de suporte e vídeo aulas com curso básico sobre C#
 

Referências:


José Carlos Macoratti