DevMedia - asp.net, Java, Delphi, SQL e web Design, tudo em um só lugar!
Bem vindo a DevMedia!
LOGIN:     SENHA:
 
 

XDocument - Manipulando arquivos XML no .NET

Veja neste artigo uma breve introdução ao XML e como usar o mesmo no .NET, veremos como manipula documentos com este formato. Usaremos a classe XDocument para fazer esta manipulação, faremos um pequeno exemplo de como é a estrutura de um XML e logo na sequencia iremos ver como consumir este mesmo XML usando uma aplicação.

[fechar]

Você não gostou da qualidade deste conteúdo?

(opcional) Você gostaria de comentar o que não lhe agradou?

Um dos formatos de arquivos mais utilizados para armazenamento de informações é, sem dúvidas, o XML, por ser um padrão compatível com a maioria das linguagens comerciais da atualidade. Um exemplo comum disso é a Nota Fiscal Eletrônica, onde os dados são enviados e recebidos neste formato, seguindo o padrão especificado pelos órgãos competentes.

O .NET Framework, como boa ferramenta que é, nos fornece uma série de recursos para trabalhar com esse tipo de arquivo, permitindo importar, exportar e consultar informações no formato XML de forma simples.

Apesar de existir mais de uma classe para esse fim, veremos neste artigo como utilizar a classe XDocument, contida no namespace System.Linq.Xml, para importar, consultar e alterar um arquivo XML de estrutura previamente conhecida.

A Listagem 1 exibe o conteúdo do arquivo pessoas.xml, utilizado nos exemplos deste artigo.

Listagem 1: Arquivo pessoas

<?xml version="1.0" encoding="UTF-8"?>
<pessoas>
	<pessoa id="1" nome="João"/>
	<pessoa id="2" nome="Maria"/>
	<pessoa id="3" nome="José"/>
</pessoas>

A estrutura é bastante simples, uma vez que objetivo deste artigo é apenas apresentar os principais métodos e propriedades da class supracitada.

Vamos então criar uma aplicação Windows forms e configurar o form principal de forma igual ou semelhante ao que ilustra a Figura 1.

Layout do form principal

Figura 1: Layout do form principal

Temos um DataGridView (dgvDados) e dois TextBoxes (txtID e txtNome) que serão utilizados para exibição e alteração dos dados.

O botão salvar funcionará da seguinte forma: caso o campo txtID contenha o ID de uma pessoa já cadastrada, o nome desta será alterado, caso contrário, um novo registro será adicionado à lista.

Para manipularmos os itens do arquivo de forma mais clara, usaremos uma classe Pessoa, conforme mostra a Listagem 2.

Listagem 2: Classe Pessoa

class Pessoa
{
    string id;
    string nome;

    public string Id
    {
        get { return id; }
        set { id = value; }
    }        

    public string Nome
    {
        get { return nome; }
        set { nome = value; }
    }
}

Temos apenas dois campos simples, da mesma forma que no arquivo XML.

Carregando o XML

Carregar o XML é, sem dúvida, a parte mais simples deste artigo. A classe XDocument dispõe de várias formas para realizar esta ação, das quais utilizaremos uma, carregando o documento a partir de seu nome. Primeiramente devemos declarar um objeto XDocument como global, seguindo o exemplo da Listagem 3. Este objeto será instanciado no evento Load do form, visto mais adiante.

Listagem 3: Declaração do objeto XDocument

XDocument doc;

Escreveremos então um método para carregar este arquivo e montar uma lista de Pessoas e exibir essa lista no grid. Devemos, em seguida, invocar este evento no evento Load do form.

Listagem 4: Carregando XML e exibindo os dados

public void CarregarXML()
{
    XDocument doc = XDocument.Load(@"C:\pessoas.xml");
    List<Pessoa> pessoas = new List<Pessoa>();
    foreach (XElement x in doc.Element("pessoas").Elements())
    {
        Pessoa p = new Pessoa()
        {
            Id = x.Attribute("id").Value,
            Nome = x.Attribute("nome").Value
        };
        pessoas.Add(p);
    }
    dgvDados.DataSource = pessoas;   
}

Lemos todos os elementos contidos no elemento “pessoas” do XML e, para cada item lido, utilizamos seus atributos para preencher um objeto do tipo Pessoa e adicioná-lo à lista. Ao fim, definimos esta lista como DataSource do grid dgvDados. Com isso, teremos todos os registros listados no grid, como pode ser visto na Figura 2.

Listados os itens do arquivo XML

Figura 2: Listados os itens do arquivo XML

O próximo passo é programar o evento SelectionChanged do grid para exibir os dados do registro selecionado nos textboxes. A Listagem 4 apresenta o código utilizado para realizar esta ação.

Listagem 4: Exibição dos dados nos textboxes

private void dgvDados_SelectionChanged(object sender, EventArgs e)
{
    if (dgvDados.SelectedRows.Count > 0)
    {
        txtId.Text = dgvDados.SelectedCells[0].Value.ToString();
        txtNome.Text = dgvDados.SelectedCells[1].Value.ToString();
    }
}

É importante que os dados sejam exibidos nos textboxes, pois utilizaremos estes valores para programar o evento Click do botão salvar, o que é mostrado na Listagem 5 a seguir.

Alterando e adicionando elementos

Listagem 5: Evento Click do botão Salvar

private void button1_Click(object sender, EventArgs e)
{
    if (doc.Element("pessoas").Elements().Where(x => x.Attribute("id").Value.Equals(txtId.Text)).Count() > 0)
    {
        XElement ele = doc.Element("pessoas").Elements().Where(x => x.Attribute("id").Value.Equals(txtId.Text)).First();
        ele.Attribute("nome").SetValue(txtNome.Text);
        doc.Save(@"C:\pessoas.xml");
        CarregarXML();
    }
    else
    {
        XElement ele = new XElement("pessoa");
        ele.Add(new XAttribute("id", txtId.Text));
        ele.Add(new XAttribute("nome", txtNome.Text));
        doc.Element("pessoas").Add(ele);
        doc.Save(@"C:\pessoas.xml");
        CarregarXML();
    }
}

Podemos agora executar a aplicação e testar. Primeiramente selecionando uma linha no grid, alterando o nome e então clicando no botão Salvar. O registro selecionado deve ser alterado e o arquivo salvo. Outro teste pode ser realizado digitando um Id inexistente, um Nome e clicando também no botão Salvar. O registro deve ser adicionado à lista e salvo no arquivo.

Como foi visto, manipular arquivos XML torna-se uma tarefa simples quando utilizamos os recursos fornecidos pelo framework. Com algumas poucas linhas de código autodescritivas, pudemos carregar um arquivo XML, alterar e inserir novos elementos e atributos em sua estrutura e salvá-lo ao fim.

Com isso finalizamos este breve artigo. Espero que o conteúdo possa ser útil.

Até a próxima.


Joel Rodrigues
Técnico em Informática - IFRN Cursando Bacharelado em Ciências e Tecnologia - UFRN Programador .NET/C# e Delphi há mais de 3 anos, já tendo trabalhado com Webservices, WPF, Windows Phone 7 e ASP.NET, possui ainda conhecimentos em HTML, CSS e Javascript (jQuery). Certificado como Microsoft Special...
O que você achou deste post?

    8 COMENTÁRIOS

[Fechar]

Este post é fechado - você precisa ter acesso ao post para incluir um comentário.



Antonio Jose Rodrigues Silva
Obrigado por este artigo.

Estou acostumado a gerar e ler xml no meu velho sistema legado, em Clipper.
Tanto pra nfe, quanto pra troca de dados com outros sistemas.

Iniciei o desenvolvimento em C# e um primeiro programa já está com sua nova versão gráfica a venda.

Uma das coisas que eu gostaria na nova versão é justamente poder ler os xmls que meu velho sistema já gera automaticamente.

Então lá vai finalmente minha duvida:
Na estrutura abaixo, como seria a leitura de cada campo ? É que o normal nos meus xmls eh ter uma tag para cada campo da tabela.

<?xml version="1.0" encoding="UTF-8"?>
<pessoas>
<pessoa seq="1">
<id>"10"</id>
<nome>"João"</nome>
</pessoa>
<pessoa seq="2">
<id>"13"</id>
<nome>"José"</nome>
</pessoa>
<pessoa seq="3">
<id>"20"</id>
<nome>"Julio"</nome>
</pessoa>
</pessoas>

Obrigado desde já pela resposta.
[há +1 mês] - Responder

 

[autor] Joel Rodrigues
Olá, Antonio. Primeiramente obrigado pelo comentário.
Bem, repare que quando eu monto a lista de Pessoas, eu atribuo os valores das propriedades do objeto buscando o conteúdo do atributo de cada item. No seu caso, ao invés de um atributo, será outro elemento, certo?
A diferença é pequena, no lugar de x.Attribute("id").Value, você usará x.Element("id").Value.
Teste e veja se consegue. Persistindo a dúvida, pode voltar a me procurar.
Um abraço.
[há +1 mês] - Responder
 

Antonio Jose Rodrigues Silva
Obrigado pela resposta.

Infelizmente eu só a vi hoje.

Eu acabei fazendo a leitura usando XmlDocument, XmlNodeList e pegando via InnerText.

Depois vou testar da maneira que vc explicou.

Obrigado mais uma vez.

Saudações
[há +1 mês] - Responder
 

[autor] Joel Rodrigues
Obrigado pelo retorno, Antonio.
Boa sorte em seus projetos.
[há +1 mês] - Responder
 

Paulo Lima
Joel, boa tarde,
Estou iniciando c# e estou "apanhando" um pouco para ler a seguinte estrutura:

<table name="load">
<r>
<c name="c0">34224</c>
<c name="c1">MENSAL</c>
<c name="c2">PAUL</c>
<c name="c3">12/3/2013 08:00:00</c>
<c name="c4">PRT</c>
<c name="c5">10</c>
<c name="c6">EA</c>
</r>
<r>
<c name="c0">34225</c>
<c name="c1">BiMESTRAL</c>
<c name="c2">JOHN</c>
<c name="c3">12/3/2013 10:00:00</c>
<c name="c4">PRC</c>
<c name="c5">10</c>
<c name="c6">MP</c>
</r>
<r>
<c name="c0">34226</c>
<c name="c1">ANUAL</c>
<c name="c2">JULLY</c>
<c name="c3">13/3/2013 08:00:00</c>
<c name="c4">PRTR</c>
<c name="c5">10</c>
<c name="c6">GM</c>
</r>
</table>

nesse caso como eu acessaria os valores?

Desde já agradeço a ajuda.

Paulo
[há +1 mês] - Responder

 

[autor] Joel Rodrigues
Olá, amigo. Tudo bem?
Primeiramente desculpe pela demora em responder, mas só agora tive acesso a um computador.
No seu caso, o documento tem o elemento raiz "table" e dentro dele, vários elementos "r". Dentro de cada elemento "r", tem-se vários elementos "c".
Com este código você consegue listar todos os valores:
----------
foreach (XElement r in doc.Element("table").Elements())
{
foreach (XElement c in r.Elements())
{
Console.Write(c.Value + " | ");
}
Console.WriteLine();
}
Console.ReadLine();
----------
Qualquer dúvida, é só falar.
[há +1 mês] - Responder
 

Eric Alves
Olá, sou novo em C# e estava seguindo o exemplo, porém ele nem percorre todo o método. Queria saber onde estou errando, desde já obrigado.

METODO:
public void CarregarXML()
{
XDocument doc = XDocument.Load(@"C:\Exemplo.xml");
List<classFuncionario> funcionarios = new List<classFuncionario>();

foreach (XElement x in doc.Element("funcionarios").Elements())
{
foreach (XElement c in x.Elements())
{
classFuncionario f = new classFuncionario()
{
Id = c.Element("id").Value,
Nome = c.Element("nome").Value
};
funcionarios.Add(f);
}

}
dgvDados.DataSource = funcionarios;
}


Arquivo XML:
<funcionarios>
<funcionario>
<id>1</id>
<nome>Joao da Silva</nome>
<endereco>Rua Dom Pedro</endereco>
<telefone>
<celular>(43)9134-8821</celular>
<fixo>
<residencial>(43)3258-9877</residencial>
<comercial>(43)3354-7865</comercial>
</fixo>
<fax>(43)3354-7864</fax>
</telefone>
<cpf>12365487612</cpf>
<rg>119459874</rg>
<sexo>Masculino</sexo>
<cidade>Londrina</cidade>
<estado>Parana</estado>
<cep>82300000</cep>
<cargo>Mecanico</cargo>
<salario>2.300</salario>
<estcivil>
<casado>
<qtdfilhos>02</qtdfilhos>
</casado>
</estcivil>
<portdeficiencia>Nao</portdeficiencia>
<valeref>400</valeref>
<valetransp>250</valetransp>
<plnsaude>Unimed</plnsaude>
<plnodonto>Indefinido</plnodonto>
</funcionario>

<funcionario>
<id>2</id>
<nome>Pedro Batista</nome>
<endereco>Rua 19 Dezembro</endereco>
<telefone>
<celular>(43)9234-8765</celular>
<fixo>
<residencial>(43)3258-4398</residencial>
<comercial>(43)3233-3245</comercial>
</fixo>
<fax>(43)3334-0987</fax>
</telefone>
<cpf>12365487345</cpf>
<rg>654459874</rg>
<sexo>Masculino</sexo>
<cidade>Cambe</cidade>
<estado>Parana</estado>
<cep>82400000</cep>
<cargo>Eletricista</cargo>
<salario>2.500</salario>
<estcivil>
<solteiro></solteiro>
</estcivil>
<portdeficiencia>Nao</portdeficiencia>
<valeref>400</valeref>
<valetransp>250</valetransp>
<plnsaude>Unimed</plnsaude>
<plnodonto>Indefinido</plnodonto>
</funcionario>
</funcionarios>
[há +1 mês] - Responder

 

[autor] Joel Rodrigues
OPa, Eric. Desculpe a demora, é que tive alguns problemas técnicos recentemente mas já foram resolvidos.
Bem, no seu caso, tem um foreach a mais aí. Você precisa percorrer apenas os elementos <funcionario> e dentro de cada um, acessar os elementos filhos com as propriedades. Veja um exemplo (modificado).
----------
foreach (XElement x in doc.Element("funcionarios").Elements())
{
classFuncionario f = new classFuncionario()
{
Id = x.Element("id").Value,
Nome = x.Element("nome").Value
};
funcionarios.Add(f);
}
----------
Qualquer dúvida, é só falar.
[há +1 mês] - Responder
 
Cursos relacionados
Publicidade
[Fechar]

Você precisa estar logado para dar um feedback.

Clique aqui para efetuar o login
[Fechar]


Este post está fechado. Saiba mais sobre a assinatura MVP!
web-03
DevMedia  |  Anuncie  |  Fale conosco
Hospedagem web por Porta 80 Web Hosting
2013 - Todos os Direitos Reservados a web-03