Pesquisar

Acompanhe

http://twitter.com/dfcdaniel Feed

Posts recentes

Comentários recentes

Criando e manipulando XML com Linq to XML

Introdução

Criar e manipular XML utilizando Linq to XML ficou muito mais fácil, existem muitas possibilidades para criar e manipular XML utilizando o .NET Framework. XPath: é uma das opções mais para tirar o máximo proveito do XPath você precisa de bons conhecimentos de expressões regulares . XmlDocument: é uma implementação da Microsoft para criação de documentos XML , conforme as especificações W3C DOM. DataSet e DataTable: eles não foram criados para manipular XML , mais muitos desenvolvedores utilizam os métodos WriteXml e ReadXml para criar e ler arquivos XML, funciona perfeitamente mais o objetivo do DataSet e DataTable é outro.

O Linq to XML, substitui todas as opções disponíveis como a vantagem de ser extremante simples, ao final desse artigo você percebera que com apenas um objeto você consegue criar e manipular arquivos XML.

Recursos utilizados

-Visual Studio 2008 Express Edition SP1.

Criando projeto

Para demonstra com utilizar o Linq to XML vamos criar uma aplicação do Tipo Console Application. Clique em File,selecione New Project e Console Application ,na caixa nome altere o valor para LinqToXMLExemplo.

Criando XML

Na definição da classe Program adiciona o campo arquivo conforme código abaixo.

static string arquivo = "C:\\documento.xml";
Dim arquivo As String = "C:\\documento.xml"

O namespace System.Xml.Linq contém todos os objetos necessários para cria e manipular XML ,para criar um arquivo XML vamos utilizar a classe XElement .Todos com atributos e elementos serão criados com os métodos SetAttributeValue e SetElementValue, para salvar o arquivo a classe disponibiliza o método Save.

Conforme o código abaixo adicione o método CriaXML a definição da classe Program e chame-o do método Main.

static void CriaXML()
{
    XElement documentoXml = new XElement("Clientes");
    XElement element = null;

    for (int i = 1; i <= 5; i++)
    {
        element = new XElement("Cliente", new XComment("Atributos do cliente " + i));

        //Atributos
        element.SetAttributeValue("Nome", String.Format("Nome {0}", i));
        element.SetAttributeValue("Endereco", String.Format("Endereço {0}", i));

        //Elementos
        element.SetElementValue("RG", String.Format("RG {0}", i));
        element.SetElementValue("CPF", String.Format("CPF {0}", i));

        //Adiciona elemento ao elemento root
        documentoXml.Add(element);
    }

    documentoXml.Save(arquivo);

    Console.WriteLine(documentoXml);
}
Sub CriaXML()
    Dim documentoXml As New XElement("Clientes")
    Dim element As XElement = Nothing

    For I As Integer = 1 To 5
        element = New XElement("Cliente", New XComment("Atributos do cliente " + I.ToString()))

        'Atributos
        element.SetAttributeValue("Nome", String.Format("Nome {0}", I))
        element.SetAttributeValue("Endereco", String.Format("Endereço {0}", I))

        'Elementos
        element.SetElementValue("RG", String.Format("RG {0}", I))
        element.SetElementValue("CPF", String.Format("CPF {0}", I))

        'Adiciona elemento ao elemento root
        documentoXml.Add(element)
    Next

    documentoXml.Save(arquivo)

    Console.WriteLine(documentoXml)
End Sub

Resultado da execução do método CriaXML.



  
    
    RG 1
    CPF 1
  
  
    
    RG 2
    CPF 2
  
  
    
    RG 3
    CPF 3
  
  
    
    RG 4
    CPF 4
  
  
    
    RG 5
    CPF 5
  

Carregar arquivo

Para carregar e selecionar valores utilizando Linq to XML podemos utilizar a classe XElement. Método Load: carregar conteúdo XML de um arquivo ou da memórias é a responsabilidade desse método, em uma de suas sobrecargas podemos passar o caminho do arquivo XML , as outras sobrecargas recebe como parâmetros um objeto TextReader ou XmlReader.Você também pode definir opções à partir do enum LoadOptions.

O LoadOption possui quatro opções . None : todas as linhas desnecessárias,linhas em branco e linhas de informações, do arquivo XML não serão carregadas. PreserveWhitespace: essa opção define que todas as linhas em branco do arquivo XML serão preservadas. SetBaseUri : essa opção define o preenchimento da propriedade BaseUri. SetLineInfo: essa opção habilita o preenchimento da das informações de linha, essa informações pode ser recuperadas através da interface IXmlLineInfo.

Conforme código abaixo adicione o método CarregaSelecionaXml na definição da classe Program e chame-o do método Main.

static void CarregaSelecionaXml()
{
    XElement xml = XElement.Load(arquivo, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo);

    //Mostra o caminho base.
    Console.WriteLine("Caminho : {0}", xml.BaseUri);

    //Mostra informações de linha 
    IXmlLineInfo lineInfo = xml as IXmlLineInfo;
    Console.WriteLine("LineNumber : {0} e LinePosition: {1}", lineInfo.LineNumber, lineInfo.LinePosition);

    //Carrega todos os elementos dentro do elemento root
    IEnumerable enumerable = xml.Elements();

    //Mostra todos os elementos dentro do elemento root
    foreach (var item in enumerable)
        Console.WriteLine(item);

    //Mostra todos os atributos nome do elento Cliente
    foreach (var item in enumerable.Attributes("Nome"))
        Console.WriteLine(item);

    //Mostra todos os elementos CPF dentro do elemento Cliente
    foreach (var item in enumerable.Elements("CPF"))
        Console.WriteLine(item);
}
Sub CarregaSelecionaXml()
    Dim xml As XElement = XElement.Load(arquivo, LoadOptions.SetBaseUri Or LoadOptions.SetLineInfo)

    'Mostra o caminho base.
    Console.WriteLine("Caminho : {0}", xml.BaseUri)

    'Mostra informações de linha 
    Dim lineInfo As IXmlLineInfo = xml

    Console.WriteLine("LineNumber : {0} e LinePosition: {1}", lineInfo.LineNumber, lineInfo.LinePosition)

    'Carrega todos os elementos dentro do elemento root
    Dim Enumerable As IEnumerable(Of XElement) = xml.Elements()

    'Mostra todos os elementos dentro do elemento root
    For Each item In Enumerable
        Console.WriteLine(item)
    Next

    'Mostra todos os atributos nome do elento Cliente
    For Each item In Enumerable.Attributes("Nome")
        Console.WriteLine(item)
    Next

    'Mostra todos os elementos CPF dentro do elemento Cliente
    For Each item In Enumerable.Elements("CPF")
        Console.WriteLine(item)
    Next
End Sub

Alterando valores

Para isso utilizamos todo o poder do Linq para selecionar o atributo ou elemento que desejamos alterar.

Conforme o código abaixo adicione o método AlterandoValores na definição da classe Program e chame-o do método Main.

static void AlterandoValores()
{
    XElement xml = XElement.Load(arquivo, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo);
    IEnumerable<XElement> elements = xml.Elements();

    //Seleciona e altera o elemento CPF aonde o valor seja igual a "CPF 1"
    foreach (var item in elements.Elements("CPF").Where(e => e.Value == "CPF 1"))
        item.Value = "123456789";

    //Seleciona e altera o atributo Nome aonde o valor seja igual a "Nome 1"
    foreach (var item in elements.Attributes("Nome").Where(e => e.Value == "Nome 1"))
        item.Value = "Nome Alterado";

    //Salva Alterações
    xml.Save(arquivo);
}
Sub AlterandoValores()
    Dim xml As XElement = XElement.Load(arquivo, LoadOptions.SetBaseUri Or LoadOptions.SetLineInfo)

    Dim elements As IEnumerable(Of XElement) = xml.Elements()

    'Seleciona e altera o elemento CPF aonde o valor seja igual a "CPF 1"
    For Each item In elements.Elements("CPF").Where(Function(e) e.Value = "CPF 1")
        item.Value = "123456789"
    Next

    'Seleciona e altera o atributo Nome aonde o valor seja igual a "Nome 1"
    For Each item In elements.Attributes("Nome").Where(Function(e) e.Value = "Nome 1")
        item.Value = "Nome Alterado"
    Next

    'Salva Alterações
    xml.Save(arquivo)
End Sub

Excluindo Valores

O código abaixo demonstra como excluir um elemento do arquivo XML, esse exemplo retira o elemento cliente aonde o atributo nome seja igual a "Nome 2", e para isso vamos utilizar mais uma vez o poder do Linq.

Conforme o código abaixo adicione o método ExcluindoValores na definição da classe Program e chame-o do método Main.

static void ExcluindoValores()
{
    XElement xml = XElement.Load(arquivo, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo);
    IEnumerable<XElement> elements = xml.Elements();

    //Exclui elemento Cliente aonde o Atributo Nome seja igual a "Nome 2"
    elements.AncestorsAndSelf("Cliente").Where(e => e.Attribute("Nome").Value == "Nome 2").Remove();

    //Salva Alterações
    xml.Save(arquivo);
}
Sub ExcluindoValores()
    Dim xml As XElement = XElement.Load(arquivo, LoadOptions.SetBaseUri Or LoadOptions.SetLineInfo)

    Dim elements As IEnumerable(Of XElement) = xml.Elements()

    'Exclui elemento Cliente aonde o Atributo Nome seja igual a "Nome 2"
    elements.AncestorsAndSelf("Cliente").Where(Function(e) e.Attribute("Nome").Value = "Nome 2").Remove()

    'Salva Alterações
    xml.Save(arquivo)
End Sub

Conclusão

Com esse simples exemplo da para se ter idéia do que o Linq to XML e capaz, a criação de manipulação de arquivos XML ficou muito mais fácil, ficou claro que o objeto XElement possui todas as funcionalidades necessárias para manipulação de arquivos XML, claro o Linq to XML não se define a um único objeto mais ele com certeza da conta do recado.

Referências

http://msdn.microsoft.com/en-us/library/bb308960.aspx

Código Fonte

Daniel Fonseca Castro

Currently rated 4.8 by 6 people

  • Currently 4.833333/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: Linq

Related posts

Comments

Daniel br

Tuesday, October 28, 2008 12:03 PM

Show de bola... me ajudou muito...

Mas como fazer para inserir novos dados em um arquivo xml que já existe e que contem registros?

Obrigado pelo artigo.

Daniel

Daniel Fonseca Castro br

Tuesday, October 28, 2008 12:04 PM

Olá Daniel

Você pode utilizar os métodos SetAttributeValue e SetElementValue, como no exemplo do método CriaXML

Daniel Fonseca Castro

Marcel Inowe br

Tuesday, October 28, 2008 12:05 PM

Parabéns Daniel, me ajudou muito seu exemplo.

Caracas meu br

Tuesday, November 04, 2008 10:27 PM

Muito bom este artigo, tiro o chapéu, como ele fica moleza entender LINQ + XML

Vlw mesmo

Gigio br

Tuesday, May 26, 2009 2:38 PM

cara sei que ja faz um tempo desde que criou este artigo...mas muito obrigado, muito bom meesmo linq é coisa bunita de deus ^^

Eduardo Melo br

Sunday, July 05, 2009 3:12 PM

Boa tarde Dan, cara se voce puder alterar o exemplo, pois para um leigo acredito que ele não saberia que o "e" referenciado dentro do where da seção de atualização do xml e na verdade o "item" instanciado dentro do proprio ForEach.

Um grande abraço.

Daniel Fonseca Castro

Sunday, July 05, 2009 6:58 PM

Olá Eduardo,

Nesse exemplo eu utilizei Lambda Expressions, veja referências
msdn.microsoft.com/pt-br/library/bb397687.aspx
msdn.microsoft.com/en-us/library/bb397687.aspx

A outra opção para construção desse exemplo seria construir as consultas sem a ajuda do método de extensão Where,utilizando linq direto, por exemplo

static void AlterandoValores()
{
XElement xml = XElement.Load(arquivo, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo);
IEnumerable<XElement> elements = xml.Elements();

//Seleciona e altera o elemento CPF aonde o valor seja igual a "CPF 1"
var cpf = (from x in elements.Elements("CPF")
where x.Value == "CPF 1"
select x).FirstOrDefault();
cpf.Value = "123456789";

//Seleciona e altera o atributo Nome aonde o valor seja igual a "Nome 1"
var nome = (from x in elements.Attributes("Nome")
where x.Value == "Nome 1"
select x).FirstOrDefault();

nome.Value = "Nome Alterado";

//Salva Alterações
xml.Save(arquivo);
}

Não sei se fica mais fácil , mais esta ai

Abraços,
Daniel Fonseca Castro

Eduardo Britto br

Friday, July 24, 2009 8:35 AM

Olá Daniel,
Parabéns pelo excelente artigo. Me ajudou muito. Ainda estou me atualizando e é muito difícil achar artigos em português com essa qualidade.
[]s

Wellington Dala br

Wednesday, July 29, 2009 10:46 AM

Ola, muito legal esse post, parabéns.

Se alguem souber, poderia me mandar um codigo de como acrescentar elementos a um documento xml.

pelo que entendi, nesse post so tem como aleterar os campos ja existentes, mas nao como acrescentar novos.

valeu.

Daniel Fonseca Castro

Wednesday, July 29, 2009 7:15 PM

Olá Wellington,

vou usar com exemplo o arquivo xml gerado nesse post!

XElement xml = XElement.Load("arquivo.xml", LoadOptions.SetBaseUri | LoadOptions.SetLineInfo);

//Adiciona elemento dentro do root
xml.SetElementValue("DentroRoot", "valor");

foreach (var item in xml.Elements())
{
//Adiciona elemento
item.SetElementValue("DentroDosElementosCliente", "Valor");

//Adiciona atributo
item.SetAttributeValue("NovoAtributoParaTodosElementosCliente", "Valor");
}
...

Resultado

<Clientes>
<Cliente Nome="Nome 1" Endereco="Endereço 1" NovoAtributoParaTodosElementosCliente="Valor">
<!--Atributos do cliente 1-->
<RG>RG 1</RG>
<CPF>CPF 1</CPF>
<DentroDosElementosCliente>Valor</DentroDosElementosCliente>
</Cliente>
....
<DentroRoot NovoAtributoParaTodosElementosCliente="Valor">valor<DentroDosElementosCliente>Valor</DentroDosElementosCliente></DentroRoot>
</Clientes>

Abraços,
Daniel Fonseca Castro

Pedro Junior

Friday, October 09, 2009 11:38 AM

Poderia mandar esse codigo fonte em c#...

Daniel Fonseca Castro br

Friday, October 09, 2009 6:10 PM

Olá Pedro,

O fonte esta disponível neste link
http://tinyurl.com/ylxuhlm

Abraços,
Daniel Fonseca Castro

Add comment


 

  Country flag

[b][/b] - [i][/i] - [u][/u]- [quote][/quote]