views:

63

answers:

1

Hi,

I have an xml file that I want to access in an WP7 and Silverlight app. Th exml file is on a webserver and I want to access is through http://www.mydomain.com/data/this_is_my_file.xml. So I want to use this url to load the xml file into an XDocument;

Any ideas,

thanks,

Filip

+1  A: 

You can use WebClient or HttpWebRequest to download (asynchronously) and parse the response. One of the simplest approach to download and parse XML from the web is below -

public void LoadXmlItems(string xmlUrl)
{
   WebClient client = new WebClient();

   client.OpenReadCompleted += (sender, e) =>
   {
        if (e.Error != null)
            return;

        Stream str = e.Result;
        XDocument xdoc = XDocument.Load(str);

        // take 10 first results
        List<RssFeedItem> rssFeedItems = (from item in xdoc.Descendants("item")
                                            select new XmlItem()
                                            {
                                                Title = item.Element("title").Value,
                                                Description = item.Element("description").Value,
                                                Url = new Uri(item.Element("link").Value, UriKind.Absolute)
                                            }).ToList();
        // close
        str.Close();

        // add results to the list
        XmlItems.Clear();
        foreach (RssFeedItem item in rssFeedItems)
        {
           XmlItems.Add(item);
        }
    };
    client.OpenReadAsync(new Uri(xmlUrl, UriKind.Absolute));
}

xmlUrl is the path to the XML file on the web. XmlItem is a class like so -

public class XmlItem
{
  public string Title { get; set; }
  public string Description { get; set; }
  public Uri Url { get; set; }
}

You need to note that you may encounter cross-thread exception if you are updating an observable collection. In the above example, XmlItems is a List<XmlItem>. However, if you wish to add the XMLItem's to an observable collection, use this piece of code instead -

Dispatcher.BeginInvoke(() =>
{
  XmlItems.Clear();
  foreach (RssFeedItem item in rssFeedItems)
  {
     XmlItems.Add(item);
  }
});

An alternative approach is to use HttpWebRequest. You can read about this approach here and use the code in the sample.

HTH, indyfromoz

indyfromoz
Hi Filip, Indy's demo code looks pretty good. I'd be inclined to use HttpWebRequest rather than WebClient if your download is anything but trivial to avoid negative impacts on your UI's performance. If your download updates the UI directly you can use the dispatcher as shown above to get around cross thread access issues, or pull the data down into a non UI container first, then load this to your ViewModel or other UI bound container via the dispatcher or back on the UI thread.
Mick N
@MickN - trying to understand your comment..... So, you think I've missed something in my answer?
indyfromoz
Nah, it's good bud, hence adding to your post rather than writing seperately, just some extra info for Filip to consider. How much it matters for Filip will depend on what he's using it for.
Mick N
it works perfectly with the webclient, thanks!
Filip
Thats great to hear, I hope my answer helped you
indyfromoz