Kotan Code 枯淡コード

In search of simple, elegant code

Menu Close

Accessing Web Services from Windows Phone 7, Part II – Parsing XML

In my previous blog post, I talked about the ways you can get data over HTTP from web services on WP7 and Silverlight. In this post, I’m going to talk about what you can do with that data once you have it.

If we had access to the full desktop or server versions of .NET 4.0, we’d be able to use classes like the XmlDocument or we’d be able to use facilities like XML serialization, which lets us work backwards from an XML string and hydrate a fully functional object graph from that. Unfortunately, neither of these facilities are available to us on WP7.

However, XDocument and LINQ to XML are available and, as you’ll see, you don’t need anything else. XDocument, which provides a fluent-style API over an XML DOM (Document Object Model), when paired with LINQ to XML, is incredibly powerful. Not just powerful, but it is also expressive and super tight. By that I mean you can rip apart an XML document into an array of ViewModel POCOs in just a few lines of code.

In the following code sample, I’m fabricating an XML document that contains a couple of stock quotes. Imagine that instead of me mocking it up, this XML document came from a live web service that provides stock quotes.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Xml.Linq;
using System.IO;
using System.Diagnostics;

namespace WindowsPhoneApplication1
{
 public class StockQuote
 {
   public string Symbol { get; set; }
   public decimal Price { get; set; }
   public DateTime QuoteTime { get; set; }
 }

 public partial class MainPage : PhoneApplicationPage
 {
   // Constructor
   public MainPage()
   {
     InitializeComponent();

     // pretend this came from a web service
     string xmlData =
     @"<ServiceReply>
       <StockQuote symbol='IBM' price='32.50' quotetime='01/01/2010 12:21:00'/>
       <StockQuote symbol='MSFT' price='21.20' quotetime='01/01/2010 12:20:30' />
      </ServiceReply>
     ";

   XDocument dataDoc = XDocument.Load(new StringReader(xmlData));

   var quotes = from quote in dataDoc.Descendants("StockQuote")
     let stamp = DateTime.Parse(quote.Attribute("quotetime").Value)
     orderby stamp ascending
     select new StockQuote
     {
       Symbol = quote.Attribute("symbol").Value,
       Price = decimal.Parse(quote.Attribute("price").Value)
     };

   foreach (StockQuote stockQuote in quotes)
   {
     Debug.WriteLine(stockQuote.Symbol + " : " + stockQuote.Price);
   }
 }
 }
}

Pay special attention to lines 43 through 50. What I’m doing here in what amounts to a single line of code is ripping open the XML, storing the important bits on POCO instances and while I’m at it, I’m specifying that I want the results sorted by a timestamp, from oldest to newest. When you run this code, you’ll notice that the output is the reverse of the document order of the original XML string.

Lines 43 through 50 truly exemplify Kotan – they are elegant in their simplicity. The code is readable, self-documenting, and it takes care of a massive amount of ceremony and grunt work that would otherwise clutter up your code. Then, when you think that the collection you just got from a web service can be merged into an ObservableCollection<StockQuote> to which your GUI is bound, things start looking pretty awesome.

So fear not – at first glance it may look like WP7 and Silverlight are hamstrung and hindered but take one look at XDocument and LINQ to XML and you’ll realize that you’ve still got an incredible amount of power and simplicity available.