Curso Windows Phone – Como ler dados de documentos XML usando LINQ como forma de consulta

xml_51Olá pessoal, tudo bom?

Uma dúvida recorrente dos DEVs Windows Phone é sobre a “leitura” de dados a partir de documentos XML e em especial aqueles que são oriundos de webservices ou chamadas REST, apesar de isso ser basicamente a mesma coisa quando os arquivos XML são locais à APP.

Para exemplificar esse post vou utilizar o retorno XML do webservice http://wcf-concursos.azurewebsites.net/Consulta.svc/xml/professor-etec, que devolve a seguinte estrutura de dados:


<ArrayOfProcessoSeletivo xmlns="http://schemas.datacontract.org/2004/07/wcf_dados.Modelo" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
 <ProcessoSeletivo>
   <Cidade>Adamantina</Cidade>
   <DataFimInscricao>2015-01-27T00:00:00</DataFimInscricao>
   <Link>http://cpssitevm.cloudapp.net/dgps/selecoespublicas/ProcessoSeletivo/055/055/01/2015/055-01-2015-ps-27-01-2015.pdf</Link>
   <NomeUnidade>Escola Técnica Estadual Professor Eudécio Luiz Vicente</NomeUnidade>
   <NumeroAviso>055/01/2015</NumeroAviso>
   <Unidade>55</Unidade>
 </ProcessoSeletivo>
 <ProcessoSeletivo>
   <Cidade>Assis</Cidade>
   <DataFimInscricao>2015-02-11T00:00:00</DataFimInscricao>
   <Link>http://cpssitevm.cloudapp.net/dgps/selecoespublicas/ProcessoSeletivo/095/095/02/2015/095-02-2015-ps.pdf</Link>
   <NomeUnidade>Escola Técnica Estadual Pedro D'Arcádia Neto</NomeUnidade>
   <NumeroAviso>095/02/2015</NumeroAviso>
   <Unidade>95</Unidade>
 </ProcessoSeletivo>
......

De posse da estrutura do XML, uma das primeiras coisas a observar é se o documento possui o atributo xmlns. Caso possua, será necessário utilizarmos a classe XNamespace para referenciar seus elementos filhos, situação que nesse exemplo iremos observar.

Declarando uma classe para representar os dados que se deseja obter do documento XML

Para facilitar o trabalho de recuperação dos dados do documento XML, indico a criação de uma classe para representação das informações desejadas. No exemplo, a classe (Escola.cs) será utilizada como base para montar uma lista com todos os nomes de escolas e cidades representadas na estrutura do XML.

namespace LeituraXML
{
  public class Escola
  {
     private string _cidade;
     public string Cidade
     {
       get { return _cidade; }
       set { _cidade = value; }
     }

     private string _nomeEscola;
     public string NomeEscola
     {
       get { return _nomeEscola; }
       set { _nomeEscola = value; }
     }
  }
}

Montando o layout da aplicação XAML

Abaixo demonstro o trecho de código do documento XAML responsável por montar a interface da aplicação. Em especial observe o elemento ListBox e seu respectivo DataTemplate. Reparem que os mesmos coincidem com a estrutura da classe Escola.cs demonstrada acima.

exemplo-xml

...
...
<StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
  <TextBlock Text="Lista de Escolas" Style="{StaticResource PhoneTextAccentStyle}" />
  <TextBlock Text="Fazendo download dos dados. Aguarde..."
             Margin="0,50,0,0" Name="txbAguarde"
             HorizontalAlignment="Center" />
  <ProgressBar IsIndeterminate="True" Name="pgbDownload" />

  <ListBox Name="lbEscolas" Height="Auto" MaxHeight="570">
    <ListBox.ItemTemplate>
      <DataTemplate>
        <StackPanel Orientation="Vertical">
          <TextBlock FontSize="30" Text="{Binding NomeEscola}" />
          <TextBlock Text="{Binding Cidade}" />
        </StackPanel>
      </DataTemplate>
    </ListBox.ItemTemplate>
  </ListBox>
</StackPanel>
...
...

Obtendo o documento XML e recuperando seus dados a partir de uma consulta LINQ

Como o documento XML que iremos tratar nesse exemplo é oriundo de uma URL, utilizaremos a classe WebClient para realizar o download do mesmo. Para mais detalhes sobre o uso do WebClient, acesse o post Classe WebClient para download de conteúdo da web no formato de dados binários ou strings.

...
namespace LeituraXML
{
  public partial class MainPage : PhoneApplicationPage
  {
    //Declaração de um WebClient para download do arquivo XML resultante da chamada REST
    WebClient wc = new WebClient();

    // Construtor
    public MainPage()
    {
      InitializeComponent();

      //Toda vez que o WebClient atualiza seu status de download o método DownloadProgressChanged será executado
      wc.DownloadProgressChanged += wc_DownloadProgressChanged;
      //Ao terminar o download do conteúdo o método DownloadStringCompleted será executado
      wc.DownloadStringCompleted += wc_DownloadStringCompleted;
      //O método DownloadStringAsync inicia o download do conteúdo especificado pela Uri
      wc.DownloadStringAsync(new Uri("http://wcf-concursos.azurewebsites.net/Consulta.svc/xml/professor-etec"), "conteudo");
    }

    void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
      //Esse if é utilizado para ter certeza que iremos processar apenas o conteúdo específico do WebClient em questão
      if (e.UserState == "conteudo")
         //O código abaixo exibe no TextBlock txtAguarde o andamento do download do documento XML
         txbAguarde.Text = e.BytesReceived.ToString() + "/" + e.TotalBytesToReceive.ToString();
    }

    void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
      //Desligando o ProgressBar
      pgbDownload.IsIndeterminate = false;
      //Caso não tenha ocorrido nenhum problema ou o processo tenha sido cancelado
      if (e.Error == null && !e.Cancelled)
      {
        //Retirando o status de progressão do download da tela
        pgbDownload.Visibility = System.Windows.Visibility.Collapsed;
        txbAguarde.Visibility = System.Windows.Visibility.Collapsed;

        /****************************************************************
         * DECLARAÇÃO DOS ELEMENTOS NECESSÁRIOS PARA RECUPERAÇÃO DOS DADOS
         * REPARE QUE OS DADOS DO DOCUMENTO ESTÃO NO OBJETO dados E QUE
         * DECLARAMOS UM OBJETO ns PARA REPRESENTAÇÃO DO NAMESPACE DO
         * DOCUMENTO XML. O NAMESPACE NÃO SERIA NECESSÁRIO SE O DOCUMENTO
         * XML NÃO TIVESSE O ATRIBUTO xmlns EM SUA DECLARAÇÃO.
        */
        XElement dados = XElement.Parse(e.Result);
        XNamespace ns = "http://schemas.datacontract.org/2004/07/wcf_dados.Modelo";

        //Recuperando os dados desejados via consulta LINQ
        var escolas = (from d in dados.Descendants(ns + "ProcessoSeletivo")
                      orderby d.Element(ns + "Cidade").Value
                      select new Escola
                          {
                            NomeEscola = d.Element(ns + "NomeUnidade").Value,
                            Cidade = d.Element(ns + "Cidade").Value
                          }).ToList();
        //Indicando a origem dos dados para o ListBox
        lbEscolas.ItemsSource = escolas;
      }
      //Tratamento de erros
      else
        txbAguarde.Text = e.Error.InnerException.ToString();
    }
...
...

Espero ter ajudado e aproveito para agradecer meus ex-alunos e colegas Renan D. Buarraj e Lucas Azambuja pelas dicas e pelo webservice.

Grande abraço,

Eduardo Henrique Rizo

MCP

Posts Relacionados: 

 

Anúncios

Coordenador de Internet da Universidade do Oeste Paulista (Unoeste) e professor universitário de disciplinas relacionadas ao desenvolvimento de sistemas para Web, gerenciamento de servidores, serviços e redes.

Marcado com: , , , , , , , , , , , ,
Publicado em Windows Phone
6 comentários em “Curso Windows Phone – Como ler dados de documentos XML usando LINQ como forma de consulta
  1. […] Como ler dados de documentos XML usando LINQ como forma de consulta […]

  2. Barrios disse:

    Excelente.

  3. costvin15 disse:

    Olá Professor, eu estou tendo alguns problemas: http://imgur.com/EmsWR9S

  4. Kayque Moreira disse:

    Olá Eduardo, você poderia fazer um tutorial básico de desenvolvimento para Windows Phone com o Visual Studio 2013 update 4 e o SDK do Windows Phone 8.1, seria de grande ajuda.

    • Bom dia Kayque, tudo bom?

      Poderia especificar um pouco melhor seu pedido? Você gostaria que eu fizesse uma vídeo aula sobre como começar a criar um projeto Windows Phone a partir do zero?

      Abraços,
      Eduardo H. Rizo

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

Sorocaba e Região
Prestadora de serviços RIZZO GS - Sorocaba/SP

Serviços de limpeza, conservação, recepção, copa, portaria, vigia, zeladoria, jardim, elétrica, hidráulica, pintura, etc.

Contato: (15) 3357-4263 / (15) 3357-4502 - contato@rizzogs.com.br

Website: http://www.rizzogs.com.br

%d blogueiros gostam disto: