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

Xampp won’t start on Windows 7

This happened to me and I recall giving up on it when I encountered it before. If you are trying to install Xampp and have stopped IIS and yet Xampp still doesn’t start, try stopping the “Web Deployment Agent Service” service at your computer management. It’s quite hard to detect as the PID when searching for port listeners is marked as PID 4 and doesn’t have a name.

<os 10013> an attempt was made to access a socket in a way forbidden by its access permissions. : make_sock: could not bind to address 0.0.0.0:80 no listening sockets available, shutting down. Unable to open logs

Thanks for the guys at stackoverflow for this http://stackoverflow.com/questions/1430141/port-80-is-being-used-by-system-pid-4-what-is-that


Using Jquery in CakePHP

In case you need to use jquery in cakephp. (not really ‘in case’, but more of ‘use it!’)

3 Things you need to take care of.

  1.  In your App Controller (if you want to use it for the whole app else you can put it at a specific controller)
    var $helpers = array( 'Javascript' );
  2.  In your default layout or your view
    link('https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js', false);
    I’m using google’s CDN for my jquery js file
  3. Test if your jquery works. Place this in your view (.ctp) file.
    $(document).ready(function(){
    $(“a”).click(function(event){
    alert(“Thanks for visiting!”);
    });
    });

Number 3 above is of course just for testing. Once you get it working you should place your js files in the webroot folder so that it’s not messy. Else you’ll be dependent on the where the view is when you change your javascript.


Testing your Facebook App in your Localhost

When creating an application that uses Facebook as an authentication method, a couple of things that you have to keep in mind so that you can test locally.

  1. Register your app at developers.facebook.com – Straight forward. This is where you’ll get your App ID, Secret ID and all them IDs.
  2. Change your app settings.
  3. This should reflect “Site URL – http://localhost.local/&#8221; and “Site Domain – localhost.local”

  4. Change your hosts file to reflect the change. This should point your 127.0.0.1 to localhost.local
    You can find the hosts file at C:\Windows\System32\drivers\etc\hosts. Make sure you run your notepad or any editing tool as administrator to be able to make the change.
  5. If you’re using IIS then you should take note of the default web site. It’s more straight forward if you’re running apache (I’m using XAMPP) as you just need to put it in the correct folder.
  6. If you didn’t get it right you’ll get an API Error Code: 191 API Error Description.
  7. When you start testing your app you should view the URL http://localhost.local/ instead of localhost only

Hope this helps and enjoy building your app!