Desenvolvimento - C#

Manipulando arquivos XML em C#

Veja neste artigo como manipular arquivos XML em C#, através de um exemplo prático no qual se lê e grava informações em arquivo.

por Joel Rodrigues



O objetivo deste artigo é mostrar, de forma breve, como trabalhar com dados em formato XML, lendo e gravando informações em arquivo. Não vamos nos preocupar com detalhes como validações e design, daremos ênfase à leitura e gravação dos dados no arquivo XML utilizando a classe XElement, contida no namespace System.Xml.Linq.

Simularemos, aqui, um cadastro simples de pessoas, contendo apenas código, nome e telefone.

O layout da tela principal

Inicialmente, criemos uma aplicação Windows Forms e, no form principal, adicionaremos alguns controles, deixando-o como na Figura 1.

 Layout da tela principal

Figura 1: Layout da tela principal

No DataGridView “gridPEssoas”, devem ser criadas três colunas, como mostra a ilustração acima. O DataProperyName das colunas deve ser, respectivamente, “Codigo”, “Nome” e “Telefone” (sem acentuação e sem aspas).

O arquivo com os dados

A seguir, adicionaremos um arquivo XML ao nosso projeto. Isso pode ser feito clicando com a direita sobre o projeto no Solution Explorer, depois em “Add” e em “New item” e então selecionar “XML File” (caso o idioma seja inglês). Neste artigo, chamaremos o arquivo de “Pessoas.xml” e o manteremos na mesma pasta que o executável.

Obervação: Para manter o arquivo na pasta do executável, clique com a direita sobre o arquivo, depois em “Properties” e altere a propriedade “Copy to Output Directory” para “Copy if newer”.

Inicialmente, definiremos o conteúdo deste arquivo conforme mostra a Listagem 1 a seguir.

Listagem 1: Conteúdo inicial do arquivo “Pessoas.xml”

<?xml version="1.0" encoding="UTF-8"?>
<pessoas>
	<pessoa codigo="1" nome="Steve Jobs" telefone="2222-2222"/>
	<pessoa codigo="2" nome="Bill Gates" telefone="3333-3333"/>
	<pessoa codigo="1" nome="Steve Ballmer" telefone="4444-4444"/>
</pessoas>

Tendo o layout da tela pronto e algumas informações para começar, podemos partir para a prática.

A classe Pessoa

Centralizaremos o código de acesso aos dados em uma classe chamada “Pessoa” (esta classe pode ser adicionada ao projeto da mesma forma que o arquivo XML, porém, selecionando “Class” ao invés de “XML File”). Esta classe possuirá apenas os três atributos citados anteriormente e alguns métodos para efetuarmos o CRUD.

O código inicial da classe Pessoa é exibido na Listagem 2.

Listagem 2: Código inicial da classe Pessoa

class Pessoa
    {
        #region Atributos
        private int codigo;
        private string nome;
        private string telefone;
        #endregion

        #region Propriedades
        public int Codigo
        {
            get { return codigo; }
            set { codigo = value; }
        }
        
        public string Nome
        {
            get { return nome; }
            set { nome = value; }
        }
        

        public string Telefone
        {
            get { return telefone; }
            set { telefone = value; }
        }
        #endregion

        #region Métodos
        //Aqui ficarão os métodos
        #endregion
    }

Dividimos o código em regiões por questão de organização. Na região “Métodos”, adicionaremos os códigos que serão vistos a seguir, com a implementação dos métodos que dão funcionalidade à classe.

Para listar os dados existentes no arquivo, utilizaremos um método estático denominado ListarPessoas() que apenas trará todos os registros contidos no arquivo (sem filtros). Porém, estes registros serão tratados como uma lista de objetos do tipo Pessoa (List) para tornar mais prático o acesso às informações. Vejamos, na Listagem 3, a implementação deste método.

Listagem 3: Método ListarPessoas()

public static List<Pessoa> ListarPessoas()
{
    List<Pessoa> pessoas = new List<Pessoa>();
    XElement xml = XElement.Load("Pessoas.xml");
    foreach(XElement x in xml.Elements())
    {
        Pessoa p = new Pessoa()
        {
            codigo = int.Parse(x.Attribute("codigo").Value),
            nome = x.Attribute("nome").Value,
            telefone = x.Attribute("telefone").Value
        };
        pessoas.Add(p);
    }
    return pessoas;
}

Quando carregamos um objeto XElement a partir de uma arquivo XML, este objeto passa a representar o elemento raiz do arquivo. No nosso caso, a raiz é o elemento que contém vários itens do tipo .

O próximo método é responsável pela inserção de novos registros e receberá como parâmetro um objeto do tipo Pessoa.

Listagem 4: Método AdicionarPessoa()

public static void AdicionarPessoa(Pessoa p)
{
    XElement x = new XElement("pessoa");
    x.Add(new XAttribute("codigo", p.codigo.ToString()));
    x.Add(new XAttribute("nome", p.nome));
    x.Add(new XAttribute("telefone", p.telefone));
    XElement xml = XElement.Load("Pessoas.xml");
    xml.Add(x);
    xml.Save("Pessoas.xml");
}

O código é de fácil entendimento. Criamos um objeto XElemento do tipo e adicionamos três atributos, um para cada propriedade da classe Pessoa. Logo após, carregamos o arquivo e adicionamos este elemento à lista, salvando o arquivo em seguida.

Vejamos agora o método responsável pela exclusão de um registro.

Listagem 5: Método ExcluirPessoa()

public static void ExcluirPessoa(int codigo)
{
    XElement xml = XElement.Load("Pessoas.xml");
    XElement x = xml.Elements().Where(p => p.Attribute("codigo").Value.Equals(codigo.ToString())).First();
    if (x != null)
    {
        x.Remove();
    }
    xml.Save("Pessoas.xml");
}

A parte mais complexa do código acima está na linha 4, onde localizamos o item a ser removido utilizando uma expressão lambda. Tendo localizado o elemento cujo atributo “código”seja igual ao código passado como parâmetro, removemos ele da lista e salvamos o conteúdo do arquivo.

Por fim, vejamos o método EditarPessoa(), que permitirá alterar os dados de um objeto pessoa, gravando-os no arquivo original.

Listagem 6: Método EditarPessoa()

public static void EditarPessoa(Pessoa pessoa)
{
    XElement xml = XElement.Load("Pessoas.xml");
    XElement x = xml.Elements().Where(p => p.Attribute("codigo").Value.Equals(pessoa.codigo.ToString())).First();
    if (x != null)
    {
        x.Attribute("nome").SetValue(pessoa.nome);
        x.Attribute("telefone").SetValue(pessoa.telefone);
    }
    xml.Save("Pessoas.xml");
}

No método EditarPessoa(), utilizamos o mesmo esquema para localizar o registro em questão. Feito isso, apenas alteramos o valor dos atributos “nome” e “telefone” e salvamos o arquivo.

Dessa forma finalizamos a classe Pessoa. Podemos então partir para a implementação das funcionalidades da tela principal.

Antes de tudo, precisamos declarar a variável global “pessoas” como uma lista de objetos Pessoa (List pessoas). Então, no evento onLoad do form, listaremos os registros existentes no arquivo, conforme mostra a Listagem 7.

Listagem 7: Evento onLoad do form

pessoas = Pessoa.ListarPessoas();
gridView.DataSource = pessoas;

Trataremos então o evento onSelectionChaged do DataGridView para que, ao selecionar um registro no grid, os dados sejam exibidos nos TextBoxes.

Listagem 8: Evento onSelectionChanged do DataGridView

if (gridPessoas.SelectedRows.Count > 0)
{
    int indice = gridPessoas.SelectedRows[0].Index;
    if (indice >= 0)
    {
        txtCodigo.Value = pessoas[indice].Codigo;
        txtNome.Text = pessoas[indice].Nome;
        txtTelefone.Text = pessoas[indice].Telefone;
    }
}

Na sequência, implementaremos o código dos botões Adicionar, Excluir e Editar.

Listagem 9: Evento onClick do botão “Adicionar”

Pessoa p = new Pessoa()
{
    Codigo = Convert.ToInt32(txtCodigo.Value),
    Nome = txtNome.Text,
    Telefone = txtTelefone.Text
};
Pessoa.AdicionarPessoa(p);
pessoas = Pessoa.ListarPessoas();
gridView.DataSource = pessoas;

Listagem 10: Evento onClick do botão “Excluir”

if (gridView.SelectedRows.Count > 0)
{
    int indice = gridView.SelectedRows[0].Index;
    Pessoa.ExcluirPessoa(pessoas[indice].Codigo);
    pessoas = Pessoa.ListarPessoas();
    gridView.DataSource = pessoas;
}

Listagem 11: Evento onClick do botão “Editar”

Pessoa p = new Pessoa()
{
    Codigo = Convert.ToInt32(txtCodigo.Value),
    Nome = txtNome.Text,
    Telefone = txtTelefone.Text
};
Pessoa.EditarPessoa(p);
pessoas = Pessoa.ListarPessoas();
gridView.DataSource = pessoas;

A cada alteração no arquivo, listamos novamente os registros para manter o grid sempre atualizado. Tendo inserido todos os códigos em seus devidos locais, basta compilar a aplicação e testar.

Como se pôde ver, trabalhar com arquivos XML é bastante simples. As classes do namespace System.Xml.Linq nos fornecem várias funcionalidades que tornam prática a manipulação deste tipo de arquivo.

Com isso, finalizamos este artigo. Até a próxima publicação.

Joel Rodrigues

Joel Rodrigues - Técnico em Informática - IFRN Cursando Bacharelado em Ciências e Tecnologia - UFRN Programador .NET/C# e Delphi há quase 3 anos, já tendo trabalhado com Webservices, WPF, Windows Phone 7 e ASP.NET, possui ainda conhecimentos em HTML, CSS e Javascript (JQuery).