.NET - Carregando XML com LINQ


LINQ - Language integrated Query - é um conjunto de recursos introduzidos no .NET Framework 3.5 que permitem a realização de consultas diretamente em base de dados , documentos XML , estrutura de dados , coleção de objetos ,etc. usando uma sintaxe parecida com a linguagem SQL.

Não importa a origem dos dados pois com LINQ podemos usar praticamente expressões semelhantes para realizar consultas tornando assim trabalho do desenvolvedor mais produtivo.

Neste artigo eu vou mostrar como podemos usar LINQ para acessar fonte de dados XML mostrando como podemos carregar as informações do arquivo XML.

Nos exemplos usados neste artigo eu vou tomar como base o arquivo XML denominado Catalago.xml que possui a seguinte estrutura:

Carregando XML com LINQ

Nossa primeira tarefa é carregar e exibir um arquivo XML usando LINQ.

A classe System.Xml.Linq.XElement representa um elemento XMl e a LINQ representa XML como uma árvore de XElements de tal forma que uma classe é usada para cada elemento a partir dos nós raiz até os nós filhos.

O método estático XElement.Load irá carregar e analisar um documento XML a partir de uma variedade de origens, retornando uma instância de XElement representando o nó raiz.

O método Load é sobrecarregado para suportar uma variedade de origens de dados XML. A seguir temos as sobrecargas:

Método Descrição
Load(Stream) Carrega os dados XML a partir de um Stream
Load(String) Carrega os dados XML a partir de um arquivo, obtido através do seu nome
Load(TextReader) Carrega os dados XML a partir de um System.IO.TextReader
Load(XmlReader) Carrega os dados XML a partir de um Stream System.Xml.XmlReader

Além disso Você pode controlar algumas das opções de carga usando a enumeração System.Xml.Linq.LoadOptions como um argumento adicional para a método Load. As opções são:

Membro Descrição
None Não preserva espaço em branco insignificante ou de base URI ou informações de linha;
PreserveWhiteSpace Preserva espaço em branco durante análise;
SetBaseUri Solicita à base de informações URI do XmlReader, e torna a disponível através da propriedade BaseUri.
SetLineInfo Solicita as informações de linha do XmlReader e torna a disponível por meio de propriedades em XObject.

A seguir vou mostrar como usar cada um dos métodos descritos acima em uma aplicação C#.

Abra o Visual C# 2010 Express Edition e crie um novo projeto Windows Forms Application com o nome LinqXML;

A seguir inclua os seguintes controles no formulário form1.cs:

Conforme o leiaute da figura abaixo:

Agora vamos declarar os namespaces usados no formulário:

using System;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Windows.Forms;

A seguir vamos declarar no início do formulário a variável para receber o nome e caminho do arquivo XML:

string nomeArquivoXML;

No evento Click do botão que irá abrir a caixa diálogo para selecionar o arquivo insira o código abaixo:

   private void btnProcurar_Click(object sender, EventArgs e)
    {
            OpenFileDialog dialogo = new OpenFileDialog();
            dialogo.Filter ="txt files (*.xml)|*.xml|All files (*.*)|*.*";
            dialogo.InitialDirectory = "C:\\dados";
            dialogo.Title = "Selecione um arquivo XML";
            if (dialogo.ShowDialog() == DialogResult.OK)
            {
                txtArquivoXML.Text = dialogo.FileName;
            }
            else
            {
                txtArquivoXML.Text = "";
            }
    }

A seguir em cada evento Click de cada botão de comando vamos incluir o código para carregar e exibir o conteúdo do arquivo XML escolhida, no nosso caso Catalogo.xml;

Para tornar mais claro e fácil o entendimento eu praticamente dupliquei o código em cada botão alterando apenas a forma de como carregar o arquivo XML usando cada método Load pertinente;

- Botão : Load(Stream)

     private void btnLoadStream_Click(object sender, EventArgs e)
        {
            if (txtArquivoXML.Text == string.Empty)
            {
                MessageBox.Show("Informe o nome do arquivo XML a carregar.", "XML", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                nomeArquivoXML = @txtArquivoXML.Text;
                try
                {
                    FileStream arquivoStream = File.OpenRead(nomeArquivoXML);
                    XElement root = XElement.Load(arquivoStream);
                    //carrega o XML no TextBox
                    txtXML.Text = root.ToString();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Erro : " + ex.Message);
                }
            }
        }

Botão : Load(String)

   private void btnLoadString_Click(object sender, EventArgs e)
   {
            if (txtArquivoXML.Text == string.Empty)
            {
                MessageBox.Show("Informe o nome do arquivo XML a carregar.", "XML", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                txtXML.Text = "";
                nomeArquivoXML = @txtArquivoXML.Text;
                try
                {
                    XElement root = XElement.Load(nomeArquivoXML);
                    //carrega o XML no TextBox
                    txtXML.Text = root.ToString();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Erro : " + ex.Message);
                }
            }
        }

Botão : Load(TextReader)

   private void btnLoadTextReader_Click(object sender, EventArgs e)
        {
            if (txtArquivoXML.Text == string.Empty)
            {
                MessageBox.Show("Informe o nome do arquivo XML a carregar.", "XML", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                txtXML.Text = "";
                nomeArquivoXML = @txtArquivoXML.Text;
                try
                {
                    TextReader reader = new StreamReader(nomeArquivoXML);
                    XElement root = XElement.Load(reader);
                    //carrega o XML no TextBox
                    txtXML.Text = root.ToString();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Erro : " + ex.Message);
                }
            }
        }

Botão : Load(XmlReader)

  private void btnLoadXmlReader_Click(object sender, EventArgs e)
        {
            if (txtArquivoXML.Text == string.Empty)
            {
                MessageBox.Show("Informe o nome do arquivo XML a carregar.", "XML", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                txtXML.Text = "";
                nomeArquivoXML = @txtArquivoXML.Text;
                try
                {
                    XmlReader xmlreader = new XmlTextReader(new StreamReader(nomeArquivoXML));
                    XElement root = XElement.Load(xmlreader);
                    //carrega o XML no TextBox
                    txtXML.Text = root.ToString();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Erro : " + ex.Message);
                }
            }
        }

O resultado vai ser o mesmo para cada um dos botões e esta exibido a seguir:

Para tornar mais clara a visualização do código usado em cada um dos métodos Load segue na tabela abaixo apenas o código referente a utilização do método no exemplo:

Método Código
Load(Stream) FileStream arquivoStream = File.OpenRead(nomeArquivoXML);
XElement root = XElement.Load(arquivoStream);
Load(String)  XElement root = XElement.Load(nomeArquivoXML);
Load(TextReader) TextReader reader = new StreamReader(nomeArquivoXML);
XElement root = XElement.Load(reader);
Load(XmlReader) XmlReader xmlreader = new XmlTextReader(new StreamReader(nomeArquivoXML));
XElement root = XElement.Load(xmlreader);

Simples , simples assim...

Pegue o projeto completo aqui:  LinqXML.zip

Eu sei é apenas LINQ , mas eu gosto...

Referências:

José Carlos Macoratti