none
Carregar ListView com Linq to XML RRS feed

  • Pergunta

  • Senhores,

    Estou precisando preencher um listview com valores dos elementos de um arquivo XML. Para isso estou usando o LINQ To XML, mas não estou sabendo com vou fazer fazer navegar. Vejam os dados.

    Conteúdo do arquivo - veiculos.xml

    <veiculos>

      <veiculo id="1">

        <placa>LNP0037</placa>

        <marca>VW</marca>

        <modelo>GOL</modelo>

        <cor>BEGE JÚPITER</cor>

      </veiculo>

      <veiculo id="2">

        <placa>LKH7691</placa>

        <marca>GM</marca>

        <modelo>CLASSIC SPIRT</modelo>

        <cor>CINZA</cor>

      </veiculo>

    </veiculos>

    Quero preencher um listaview da sequinte forma:

     XDocument xmlDoc = XDocument.Load("veiculos.xml");

                var query = from v in xmlDoc.Elements("veiculos")

                            select v;

                ListViewItem item = new ListViewItem();

                if (query.Count()>0)

                {

                    foreach (XElement veiculo in query)

                    {

                        item.Text = veiculo.Attribute("id").Value;

                        item.SubItems.Add(veiculo.Element("placa").Value);

                        item.SubItems.Add(veiculo.Element("marca").Value);

                        item.SubItems.Add(veiculo.Element("modelo").Value);

                        item.SubItems.Add(veiculo.Element("cor").Value);

                        listView1.Items.Add(item);

                    }

                }

     

    Sendo que logo na primeira linha onde o programa faz leitura do atributo ocorre o erro "Referência de objeto não definida para uma instância de um objeto."

     

    Alguém poderia me ajudar?


    Carlos Henrique Meireles
    terça-feira, 10 de agosto de 2010 02:46

Respostas

  • Carlos,

    Nesse caso, o código ficaria assim:

          XDocument xmlDoc = XDocument.Load(@"d:\abc.xml");
    
          var query = from v in xmlDoc.Descendants("veiculo")
                select new
                {
                  id = v.Attribute("id").Value,
                  placa = v.Element("placa").Value,
                  marca = v.Element("marca").Value,
                  modelo = v.Element("modelo").Value,
                  cor = v.Element("cor").Value
                };
    
          // Detalhe: quando você quiser saber se a query tem algum "registro", utilize o .Any() que tem 
          // uma performance melhor que Count() > 0.
          if (query.Any())
          {
            foreach (var veiculo in query)
            {
              ListViewItem item = new ListViewItem();
    
              item.Text = veiculo.id;
              item.SubItems.Add(veiculo.placa);
              item.SubItems.Add(veiculo.marca);
              item.SubItems.Add(veiculo.modelo);
              item.SubItems.Add(veiculo.cor);
              listView1.Items.Add(item);
            }
          }
    
    

    André Alves de Lima
    Visite o meu site: http://andrealveslima.spaces.live.com
    Me siga no Twitter: @andrealveslima
    quarta-feira, 11 de agosto de 2010 11:55
    Moderador

Todas as Respostas

  • Olá,
    Tenta este código

     

    var result = (from cars in doc.Descendants("veiculo")
    select new
    {
    Id = cars.Attribute(
    "id").Value,
    Placa = cars.Element(
    "placa").Value,
    Marca = cars.Element(
    "marca").Value,
    Modelo = cars.Element(
    "modelo").Value,
    Cor = cars.Element(
    "cor").Value
    }).ToList();

    Anderson

    terça-feira, 10 de agosto de 2010 12:06
  • Henrique,

    Troque xmlDoc.Elements("veiculos") para xmlDoc.Descendants("veiculo")


    André Alves de Lima
    Visite o meu site: http://andrealveslima.spaces.live.com
    Me siga no Twitter: @andrealveslima
    terça-feira, 10 de agosto de 2010 12:16
    Moderador
  • Anderson,

     

    Depois que fiz a sua alteração sugerida, o compilador está dando o seguinte erro na linha do Foreach 

    Cannot convert type 'AnonymousType#1' to 'System.Xml.Linq.XElement' 

    Na sua sugestão como poderei navegar pelas linhas retornadas para popular o ListView?



    Carlos Henrique Meireles
    terça-feira, 10 de agosto de 2010 22:39
  • André,

     

    Deu certo a alteração que tu sugeriste. No exemplo acima, para simplificar, eu coloquei select v, porém o elemento VEICULO não tem só id,placa, marca, modelo e cor, tem muito mais elementos (campos). Acontece que nessa consulta só me interessa esses elementos, pois são eles que precisarei exibir no listview. 

    Daí eu fiz assim: 

     

     var query = from v in xmlDoc.Descendants("veiculo")

                            select new

                            {

                                id = v.Attribute("id").Value,

                                placa = v.Element("placa").Value,

                                marca = v.Element("marca").Value,

                                modelo = v.Element("modelo").Value,

                                cor = v.Element("cor").Value

                            };

    Depois que tentei compilar deu o seguinte erro o foreach

    Error 1 Cannot convert type 'AnonymousType#1' to 'System.Xml.Linq.XElement'

     

    Qual é o forma correta para navegar pela query através do Foreach?

    Detalhe: Antes dessa alteração o tipo da variável query estava com o tipo IEmumerable<xElement>, depois da alteração a variável passou a ser IEmumerable<a>, onde "a" é um tipo anônimo.

    Por que isso aconteceu?


     


    Carlos Henrique Meireles
    terça-feira, 10 de agosto de 2010 22:52
  • Carlos,

    Nesse caso, o código ficaria assim:

          XDocument xmlDoc = XDocument.Load(@"d:\abc.xml");
    
          var query = from v in xmlDoc.Descendants("veiculo")
                select new
                {
                  id = v.Attribute("id").Value,
                  placa = v.Element("placa").Value,
                  marca = v.Element("marca").Value,
                  modelo = v.Element("modelo").Value,
                  cor = v.Element("cor").Value
                };
    
          // Detalhe: quando você quiser saber se a query tem algum "registro", utilize o .Any() que tem 
          // uma performance melhor que Count() > 0.
          if (query.Any())
          {
            foreach (var veiculo in query)
            {
              ListViewItem item = new ListViewItem();
    
              item.Text = veiculo.id;
              item.SubItems.Add(veiculo.placa);
              item.SubItems.Add(veiculo.marca);
              item.SubItems.Add(veiculo.modelo);
              item.SubItems.Add(veiculo.cor);
              listView1.Items.Add(item);
            }
          }
    
    

    André Alves de Lima
    Visite o meu site: http://andrealveslima.spaces.live.com
    Me siga no Twitter: @andrealveslima
    quarta-feira, 11 de agosto de 2010 11:55
    Moderador