views:

261

answers:

2

I'm querying a Twitter RSS feed and supplying the results into a Repeater for display. I'd like to only get the first 5 results of the XPath query. Is there a way to do that in the XPath syntax or do I have to loop over the resulting XmlNodeList to pull out the first 5?

XmlDocument doc = new XmlDocument();
XmlTextReader reader = new XmlTextReader(rssPath);
doc.Load(reader);

XmlNodeList items = doc.SelectNodes("/rss/channel/item");

rptTwitter.ItemDataBound += new RepeaterItemEventHandler(rptTwitter_ItemDataBound);
rptTwitter.DataSource = items;
rptTwitter.DataBind();
+3  A: 

Try this XPath query instead:

(/rss/channel/item)[position() <= 5]

It returns only the first five matching items. The parentheses are important, as without them the [position() <= 5] part applies to the item element's position in its parent rather than its position in the result node set.

Welbog
This is exactly what I need in my current situation. Thanks!
Mark Ursino
+4  A: 

If you want to continue using xpath then you should look at the position() method in xpath. Using a predicate something like this...

[position() < 6]

... should result limit the results to only the first 5 items. Welbog's answer is your best reference here (+1 to Welbog).

However, if you're able to use .NET 3.5 then I would recommend you look at my answer here...

http://stackoverflow.com/questions/811074/what-is-the-coolest-thing-you-can-do-in-10-lines-of-simple-code-help-me-inspir/811236#811236

... and take a look at the syndication APIs that make dealing with RSS feeds much easier. Then, if you only want 5 items, use the LINQ method Take on the collection to take a specific number of items.

This will allow you to express yourself better and not have to worry about the structure of the feed, namespaces etc.

I realise this isn't directly answering your question but as many people don't know about these new APIs in .NET I thought I'd mention them here.

So, your code to get just 5 items would be something like this...

var xmlr = XmlReader.Create("http://twitter.com/statuses/public_timeline.rss")
var first5Items = SyndicationFeed
                    .Load(xmlr)
                    .GetRss20Formatter()
                    .Feed
                    .Items
                    .Take(5);
Martin Peck
Martin, thanks! This is a great alternative and I think I'll be using this more often. I'm not sure if my client's server is 3.5 so I'm staying away from LINQ right now but if I find out they have it, I'll use this. I just tried it locally and it works like a charm. I love having the actual properties for the RSS nodes.
Mark Ursino