LINQ to XML on Windows Phone 7

I was dabbling with Windows Phone 7 and I hit a bit of a snag with LINQ to XML as I need to access a web service that returns XML. I’m using http://isbndb.com/ API to access book information.

It’s a pretty standard task and most applications nowadays access some form of web services to add functionality to their apps. Just so you know, there are tons of resources online but I had to do a bit more debugging thus my guide (which I usually do for myself just in case I forget:) )

Make sure to check out Scott Gu’s excellent Twitter App tutorial that uses LINQ to XML. If you’re having a bit of difficulty grasping the concept, head over to MSDN as they have a very good overview/explanation of LINQ to XML.

On to my code.

I needed to download the XML based on my query string (easy enough) and I’ll get an output like this

- <ISBNdb server_time="2012-01-07T07:03:57Z">
- <BookList total_results="47" page_size="10" page_number="1" shown_results="10">
- <BookData book_id="akrasia_thief_of_time" isbn="1891153048" isbn13="9781891153044">
  <Title>Akrasia, Thief of Time</Title> 
  <TitleLong>Akrasia, Thief of Time (Eden Odyssey D20)</TitleLong> 
  <AuthorsText>David Chart,</AuthorsText> 
  <PublisherText publisher_id="eden_studios">Eden Studios</PublisherText> 
  </BookData>
- <BookData book_id="a_thief_on_morgans_plantation" isbn="1881889629" isbn13="9781881889625">
  <Title>A Thief on Morgan's Plantation</Title> 
  <TitleLong>A Thief on Morgan's Plantation (Mysteries in Time)</TitleLong> 
  <AuthorsText>Lisa Banim, Tatyana Yuditskaya (Illustrator)</AuthorsText> 
  <PublisherText publisher_id="silver_moon_press">Silver Moon Press</PublisherText> 
  </BookData>
  </BookList>
  </ISBNdb>
     

So it’s your job to make sense out of that output.

When using LINQ to XML make sure you include references to System.Xml.linq.

Downloading and querying the Web Service is straight forward.


private void search_book(object sender, RoutedEventArgs e)
        {
             Uri serviceUri = new Uri(("http://isbndb.com/api/books.xml?access_key=XXXXXXXX&index1=title&value1=" + Title_textbox.Text ));

            WebClient client = new WebClient();

            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(downloader_Completed);
            client.DownloadStringAsync(serviceUri);

        }

search_book is just an event handler for a button or “enter”.
The Uri is where you put the web service then I parse with my search item.
WebClient handles all the webby stuff.
There’s a bunch of ways you can do the next step but all it does is proceed to downloader_Completed once the download is complete. That’s where all the LINQ stuff comes in as you already have the XML. Now it’s time to make sense of it.
You need the DownloadStringAsync with the URI that we defined awhile ago.

void downloader_Completed(object sender, DownloadStringCompletedEventArgs e)
        {

            if (e.Error != null)
                return;

            XElement booksDL = XElement.Parse(e.Result);

            var list = (from c in booksDL.Descendants("BookData")
                        select
                            new book_class
                            {
                                Book_title = c.Element("Title").Value
                            }).ToList();

            ObservableCollection books = new ObservableCollection(list);
            listBox1.ItemsSource = books;

        }

Line 4 – First off, if there’s an error just exit out of the function.
Line 7 – MSDN has a good article on the different classes that you can use when using LINQ to XML. Depends on your needs, but XElement usually is good enough for basic stuff.
Line 9 – This is where all my pain arised. Not being used to how XML are traversed along with the multitude of methods in XElement, I seeked help from my awesome friends and Bok showed me how to debug it.
Line 11 – Of course you need a class to be able to receive the data so I created a book_class with the appropriate properties. (I simplified the example to only handle book_title)

namespace librarian
{
    public class book_class
    {
        public string Book_title { get; set; }
    }
}

Make sure that you are getting something back.
You would need a good idea of what the structure of the XML is so that you know what method to use. The ISBNdb XML return is about 3 nodes deep but the concept is pretty much the same for any XML return.

In this example I was trying to figure out if I’m getting anything back based on my query and it looks like I got the correct entries.

Lastly, line 16 & 17 just passes the list to listbox that I have defined in the XAML. Bok suggested to use ObservableCollection as it updates the variable in case your data has changed as it always “observes the collection”.
Once you pass it to the listbox, you can have more event handlers there like when they click an entry.

That’s it for my simple tutorial of LINQ to XML. Of course, there are a lot more resources out there but I wanted to focus on the simplicity of my example to get to you to access web services easily.

If you have any questions, please feel free to comment and if you think there are better ways to do my example, please do suggest.

Advertisements


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s