Jeffrey Palermo (.com)

Sponsors

The Lounge

News

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Linq to Xml - querying an RSS feed

Linq (and all its flavors) will come out with .Net 3.5 and Visual Studio 2008. Along with the Xml support are classes such as XDocument, XElement, XAttribute, etc. What's interesting about XElement in particular is that it allows us to load some Xml from many sources and query into it. Depending on your experience with XPath, an Xml Linq query may be easier to write AND read.

Let's look at a sample Linq to Xml query. I'm going to use my blog's RSS feed, http://feeds.feedburner.com/jeffreypalermo.

Let's start simple. We'll read in the Xml from the RSS feed and enumerate through all the posts (or "items" in the RSS world).

XElement rssFeed = XElement.Load(@"http://feeds.feedburner.com/jeffreypalermo");


    
var items = from item in rssFeed.Elements("channel").Elements("item")
 select item;


    
Console.WriteLine(items.Count());
foreach (object o in items)
{
 Console.WriteLine(o);
}

Note that we are merely reading in the feed into an XElement and then selecting all item nodes from the document.

That's pretty interesting that we can filter to only the "item" nodes that quickly, but what if I want to find the posts with the author of "Jeffrey Palermo" (never mind that this is my feed, but imagine it was a composite feed).

XNamespace dc = "http://purl.org/dc/elements/1.1/";


    
XElement rssFeed = XElement.Load(@"http://feeds.feedburner.com/jeffreypalermo");


    
var items = from item in rssFeed.Elements("channel").Elements("item")
 where item.Element(dc + "creator").Value == "Jeffrey Palermo"
 select item;


    
Console.WriteLine(items.Count());
foreach (object o in items)
{
 Console.WriteLine(o);
}

I gave this example to illustrate how to use the XNamespace class to help filter in nodes that declare a namespace prefix such as "dc:creator" in an RSS feed. Note the "where" clause in my Linq query.

Let's go further and filter down to just the posts that contain the term "altnetconf" (or choose another term to search for)

XNamespace dc = "http://purl.org/dc/elements/1.1/";


    
XElement rssFeed = XElement.Load(@"http://feeds.feedburner.com/jeffreypalermo");


    
var items = from item in rssFeed.Elements("channel").Elements("item")
 where item.Element(dc + "creator").Value == "Jeffrey Palermo"
 && item.Element("description").Value.Contains("altnetconf")
 select item;


    
Console.WriteLine(items.Count());
foreach (object o in items)
{
 Console.WriteLine(o);
}

Now we've seen how the where clause functions. Let's shape the data now. I'll drop the where clause for simplicity, and I want to grab my feed and put a title and abstract into a collection for use in my application. I'll use an anonymous type to help me do that.

XElement rssFeed = XElement.Load(@"http://feeds.feedburner.com/jeffreypalermo");


    
var items = from item in rssFeed.Elements("channel").Elements("item")
 select new { Title = item.Element("title").Value, 
 Abstract = item.Element("description").Value.Substring(0, 100) }
;


    
Console.WriteLine(items.Count());
foreach (object o in items)
{
 Console.WriteLine(o);
}

Here, I have created an anonymous type with a Title and Abstract. Now that I have the information in object form, I can work with it. I would not want to work with Xml throughout my application, but only at the edges. I prefer to pull in the information and get it into my domain model as quickly as possible because objects are easier to work with that raw Xml.

I'm not finished yet because my type doesn't have a name, so there is no way I can pass my IEnumberable<whateverthetypeis> to another part of my application. I need to hydrate one of my domain objects so I can work with my abstracts.

I'm going to use this class:

public class PostAbstract
{
 private string _title;
 private string _abstract;


    
 public string Title
 {
 get { return _title; }
 set { _title = value; }
 }


    
 public string Abstract
 {
 get { return _abstract; }
 set { _abstract = value; }
 }
}

I'll have the results of my Xml query create a set of PostAbstracts, and then I can work with them.

XElement rssFeed = XElement.Load(@"http://feeds.feedburner.com/jeffreypalermo");


    
IEnumerable<PostAbstract> items = from item in rssFeed.Elements("channel").Elements("item")
 select new PostAbstract { Title = item.Element("title").Value, 
 Abstract = item.Element("description").Value.Substring(0, 100) }
;


    
Console.WriteLine(items.Count());
foreach (PostAbstract anAbstract in items)
{
 Console.WriteLine("{0} - {1}", anAbstract.Title, anAbstract.Abstract);
}

Note that I merely gave my type a name, PostAbstract. I used object initializers to set the properties, and now I have a set of objects I can work with to accomplish my purpose.

If you enjoyed this article, subscribe to my feed: http://feeds.feedburner.com/jeffreypalermo


Posted Sat, Oct 13 2007 12:49 PM by Jeffrey Palermo

[Advertisement]

Comments

GadgetGadget.info - Gadgets on the web » Linq to Xml - querying an RSS feed wrote GadgetGadget.info - Gadgets on the web &raquo; Linq to Xml - querying an RSS feed
on Sat, Oct 13 2007 3:11 PM

Pingback from  GadgetGadget.info - Gadgets on the web &raquo; Linq to Xml - querying an RSS feed

J. M. Aguilar wrote re: Linq to Xml - querying an RSS feed
on Sat, Oct 13 2007 3:27 PM

Good post, Jeffrey. It illustrates very well how Linq can help us in the near future.

DonXML wrote re: Linq to Xml - querying an RSS feed
on Sat, Oct 13 2007 7:26 PM

Add the VB version is even easier to read and write, with no perf difference from C#!

Dim items = From item In rssFeed.<channel>.<item> _

                   Select New PostAbstract With {.Title = item.<title>.Value, _

                           .Abstract = item.<description>.Value.Substring(100)}

and handling namespaces is even easier.  You declare namespaces as import statements:

Imports <xmlns:dc="purl.org/.../">

And then refeerence them:

Dim items = From item In rssFeed.<channel>.<item> _

           Where item.<dc:creator>.Value = "Jeffrey Palermo" _

            Select item

Works the same way when writing XML

It you don't want to write your whole app in VB, you can use Hanselman's ILMerge technique: www.hanselman.com/.../MixingLanguagesInASingleAssemblyInVisualStudioSeamlesslyWithILMergeAndMSBuild.aspx

Jeremy D. Miller wrote re: Linq to Xml - querying an RSS feed
on Sat, Oct 13 2007 8:00 PM

Isn't there something in the CodeBetter bylaws about VB.NET?

Marc Fairorth wrote re: Linq to Xml - querying an RSS feed
on Sun, Oct 14 2007 12:37 AM

VB.Net, its the ultimate Alt.Net experience!

Joe Ocampo wrote re: Linq to Xml - querying an RSS feed
on Sun, Oct 14 2007 4:12 AM

Looks like your post are suffering from the same "&#xA0;" Live Writer Beta 3 bug that I have.  Gotta love a double space after an end of sentence. ;-)

Jeffrey Palermo wrote re: Linq to Xml - querying an RSS feed
on Sun, Oct 14 2007 11:42 PM

@Joe,

Yeah, I had to manually fix the &#xA0;

Jeffrey Palermo wrote re: Linq to Xml - querying an RSS feed
on Sun, Oct 14 2007 11:43 PM

@DonXML,

Yep, I demoed the VB xml schema intellisense at the Austin DevCares event last Friday.  It is cool how by importing the schema one could access the Xml with better syntax.

Jeffrey Palermo wrote re: Linq to Xml - querying an RSS feed
on Sun, Oct 14 2007 11:45 PM

@Jeremy,

Nope, but I wonder if there is Linq support in J#. . . oh that's right, Microsoft silently deprecated that language.

Linq to Xml - querying an RSS feed « vincenthome’s Software Development wrote Linq to Xml - querying an RSS feed &laquo; vincenthome&#8217;s Software Development
on Mon, Oct 15 2007 3:16 PM

Pingback from  Linq to Xml - querying an RSS feed &laquo; vincenthome&#8217;s Software Development

DonXML wrote re: Linq to Xml - querying an RSS feed
on Mon, Oct 15 2007 3:33 PM

@Jeffrey

You don't need a schema to use XML Properties (that's what they are called), but it does help with the intellisense.

Jim Wooley wrote re: Linq to Xml - querying an RSS feed
on Thu, Oct 18 2007 10:23 AM

In addition to querying the raw XML, you can use the new SyndicationFeed in the 3.5  System.ServiceModel.Web library to load feeds in either RSS or ATOM and have strongly typed results which you can then query through LINQ to Objects. See devauthority.com/.../85717.aspx for a sample implementation.

Thomas goes .NET wrote LINQ to Productivity
on Mon, Jan 28 2008 5:03 AM

Wer erinnert sich noch an das Getöse vor dem Launch von .NET 2.0 und Visual Studio 2005 vor ziemlich genau zwei Jahren? Damals konnte man auf jedem Evangelisten-Vortrag hören, wie sehr die neue .NET-Generation die Produktivität steigert und wie viel