Olá 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.
... ... <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
Posts Relacionados:
- Curso Windows Phone gratuito
- Como preencher e identificar os itens selecionados em um ListBox
- Exemplo de binding usando Listbox
- Como obter acesso a controles dentro do ItemTemplate do ListBox
- Como consumir dados de webservices
[twitter-follow screen_name=’eduardorizo’ show_count=’yes’]
Pingback: Free: Curso Windows Phone – Vários tópicos | Blog do Eduardo H. Rizo
Excelente.
Olá Professor, eu estou tendo alguns problemas: http://imgur.com/EmsWR9S
Olá, tudo bom?
Basta você fazer inserir o namespace System.Xml.Linq no início do arquivo MainPage.xaml.cs.
Abraços,
Eduardo H. Rizo
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