C# - Modificando a estrutura de um arquivo XML com LINQ


Uma dos aspectos notáveis da plataforma .NET é a sua grande integração com XML. Em muitas aplicações você pode usar XML sem se preocupar, a plataforma lhe dá suporte realizando tarefas como a serialização de DataSets, chamando um web service, lendo arquivos de configuração, etc. Mas se você precisar trabalhar diretamente com XML o namespace System.Xml permite manipular dados XML facilmente. As tarefas mais comuns incluem analisar arquivos XML, validar um schema, aplicar transformações usando XLST em arquivos XML para criar um novo documento ou realizar buscas inteligentes usando o XPath.

A partir da versão 3.5 a Microsoft incluiu o LINQ to XML o qual integra a manipulação XML com o modelo LINQ para consulta de fontes de dados oferecendo assim mais possibilidades e opções de tratamento XML.

Neste artigo vamos mostrar modificar um arquivo XML usando LINQ.

Para realizar esta tarefa vamos usar os métodos Add, Replace e Remove da classe XElement.

O primeiro passo para adicionar, remover ou modificar uma árvore XML é selecionar o elemento que queremos alterar. Podemos fazer isso usando uma consulta LINQ, ou através dos métodos Attribute e Element da classe XElement.

Eu vou usar o Visual Studio 2012 Express for Desktop e a linguagem C# e criar uma solução (File->New Project) Windows Forms Application chamada XML_CRUD_CSharp.

No formulário form1.cs vamos os seguintes controles:

O leiaute do formulário form1.cs deverá ter a seguinte aparência:

Vamos criar um arquivo XML que será usado no projeto. No menu PROJECT clique em Add New Item e a seguir selecione o template XML File e informe o nome Catalogo2013.xml e clique em Add;

A seguir digite o código abaixo onde definimos um arquivo XML de produtos com nome, descricao, preco e estoque:

Este arquivo estará localizado na raiz do projeto.

Alterando a estrutura do XML

Vamos agora realizar as operações para alterar a estrutura do arquivo XML criado acima.No formulário form1.cs vamos colocar todo o código necessário para realizar as alterações.

Para isso teremos que declarar os seguintes namespaces no início do formulário form1.cs:

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

A seguir, logo após a declaração da classe form1 devemos definir as variáveis que deverão ser visíveis em todo o formulário:

XElement rootElem;
IEnumerable<XElement> prodElementos;

1- Selecionado e exibindo o arquivo XML

Para selecionar um arquivo XML de uma origem definida usando o controle OpenFileDialog definido no código do evento Click do botão de comando btnProcuraXML:

  private void btnProcuraXML_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd1 = new OpenFileDialog();
  
            //define as propriedades do controle 
            //OpenFileDialog
            ofd1.Multiselect = false;
            ofd1.Title = "Selecionar XML";
            ofd1.InitialDirectory = @"C:\Dados\";
            //filtra para exibir somente arquivos XML
            ofd1.Filter = "Images (*.XML)|*.XML|" + "All files (*.*)|*.*";
            ofd1.CheckFileExists = true;
            ofd1.CheckPathExists = true;
            ofd1.FilterIndex = 2;
            ofd1.RestoreDirectory = true;
            ofd1.ReadOnlyChecked = false;
            ofd1.ShowReadOnly = false;

            DialogResult dr = ofd1.ShowDialog();
            if (dr == System.Windows.Forms.DialogResult.OK)
            {
                txtArquivoXML.Text = "";
                // Le os arquivos selecionados 
                foreach (String arquivo in ofd1.FileNames)
                {
                    txtArquivoXML.Text += arquivo;
                }
            }
        }

Para exibir o arquivo temos o código a seguir no evento Click do botão btnCarregaXML;

  private void btnCarregaXML_Click(object sender, EventArgs e)
   {
            try
            {
                // carrega e exibe o arquivo XML
                rootElem = XElement.Load(@txtArquivoXML.Text);
                txtXML.Text = rootElem.ToString();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Erro ao carregar arquivo : " + ex.Message);
            }
        }

Para o nosso exemplo estamos carregando o arquivo Catalogo2013.xml que é exibido conforme a figura a seguir:

2- Selecionando e alterando a estrutura do arquivo XML

No evento Click do botão btnSelecionarElementosProdutos vamos incluir o código abaixo que seleciona e exibe os elementos Produtos;

private void btnSelecionarElementosProdutos_Click(object sender, EventArgs e)
 {
            try
            {
                txtXML.Text = "";
                prodElementos = from elem in rootElem.Element("produtos").Elements()
                                         where (elem.Name == "produto")
                                         select elem;

                foreach (XElement elemento in prodElementos)
                {
                    txtXML.Text += "Produtos " + elemento.ToString();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Erro  : " + ex.Message);
            }
   }

Abaixo vemos os elementos selecionados exibidos no TextBox - txtXML:

No botão Alterar o atributo ID dos Produtos temos o código que percorre os elementos selecionados e usando o atributo ReplaceAttributes altera o ID dos produtos adicionando o valor 100:

  private void btnAlteraAtributo_Click(object sender, EventArgs e)
  {
            try
            {
                // Percorre os elementos e altera o atributo ID
                foreach (XElement elem in prodElementos)
                {
                    // Pega o ID do produto atual
                    int id_atual = Int32.Parse((string)elem.Attribute("id"));
                    // Altera o atributo usando ReplaceAttributes
                    elem.ReplaceAttributes(new XAttribute("id", id_atual + 100));
                }
                txtXML.Text = rootElem.ToString();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Erro  : " + ex.Message);
            }
        }

3- Removendo elementos do arquivo XML

No botão btnRemoveAtributos o código a seguir remove os elementos contendo a palavra 'VB' na descrição usando o método Remove:

private void btnRemoveAtributos_Click(object sender, EventArgs e)
 {
            try
            {
                // remove todos os elementos que contenham a palavra "VB" na descricao
                IEnumerable<XElement> VBElementos = from elem in
                                                    rootElem.Element("produtos").Elements()
                                                    where (((string)elem.Element("descricao")).Contains("VB"))
                                                    select elem;

                foreach (XElement elem in VBElementos)
                {
                    elem.Remove();
                }

                txtXML.Text = rootElem.ToString();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Erro  : " + ex.Message);
            }
        }

4- Adicionando um novo elemento no arquivo XML

Finalmente no evento Click do botão de comando btnAdicionaElemento estamos adicionando um novo elemento no arquivo XML usando o método Add:

  private void btnAdicionaElemento_Click(object sender, EventArgs e)
  {
            try
            {
                // Define e adiciona um novo elemento
                XElement novoElemento = new XElement("produto", new XAttribute("id", 2000),
                new XElement("produtoNome", "Super CD Vídeo Aulas"),
                new XElement("descricao", "Vídeo Aulas para VB .NET, C# e ASP .NET"),
                new XElement("produtoPreco", 60.00),
                new XElement("estoque", true));

                rootElem.Element("produtos").Add(novoElemento);

                txtXML.Text = rootElem.ToString();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Erro  : " + ex.Message);
            }
 }

 

Pegue o projeto completo aqui: XML_CRUD_CSharp.zip

João 3:27 Respondeu João: O homem não pode receber coisa alguma, se não lhe for dada do céu.

João 3:28 Vós mesmos me sois testemunhas de que eu disse: Não sou o Cristo, mas sou enviado adiante dele.

João 3:29 Aquele que tem a noiva é o noivo; mas o amigo do noivo, que está presente e o ouve, regozija-se muito com a voz do noivo. Assim, pois, este meu gozo está completo.

João 3:30 É necessário que ele cresça e que eu diminua.

Referências:


José Carlos Macoratti