mch_dk
mch_dk

Reputation: 369

LINQ query problem

Can't get any result in feeds. feedXML has the correct data.

XDocument feedXML = XDocument.Load(@"http://search.twitter.com/search.atom?q=twitter");

var feeds = from entry in feedXML.Descendants("entry")
            select new
            {
                PublicationDate = entry.Element("published").Value,
                Title = entry.Element("title").Value
            };

What am I missing?

Upvotes: 1

Views: 284

Answers (4)

IndigoDelta
IndigoDelta

Reputation: 1481

The issue is in feedXML.Descendants("entry"). This is returning 0 results According to the documentation you need to put in a fully qualified XName

Upvotes: 0

Paul
Paul

Reputation: 36

You need to specify a namespace on both the Descendents and Element methods.

XDocument feedXML = XDocument.Load(@"http://search.twitter.com/search.atom?q=twitter");

XNamespace ns = "http://www.w3.org/2005/Atom";
var feeds = from entry in feedXML.Descendants(ns + "entry")
            select new
            {
            PublicationDate = entry.Element(ns + "published").Value,
            Title = entry.Element(ns + "title").Value
            };

Upvotes: 2

ColinE
ColinE

Reputation: 70122

If you look at the XML returned by the HTTP request, you will see that it has an XML namespace defined:

<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" ...>
  <id>tag:search.twitter.com,2005:search/twitter</id>
  ...
</feed>

XML is just like C#, if you use an element name with the wrong namespace, it is not considered to be the same element! You need to add the required namepsace to your query:

private static string AtomNamespace = "http://www.w3.org/2005/Atom";

public static XName Entry = XName.Get("entry", AtomNamespace);

public static XName Published = XName.Get("published", AtomNamespace);

public static XName Title = XName.Get("title", AtomNamespace);

var items = doc.Descendants(AtomConst.Entry)
                .Select(entryElement => new FeedItemViewModel()
                new {
                  Title = entryElement.Descendants(AtomConst.Title).Single().Value,
                  ...
                });

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1499790

You need to specify the namespace:

// This is the default namespace within the feed, as specified
// xmlns="..." 
XNamespace ns = "http://www.w3.org/2005/Atom";

var feeds = from entry in feedXML.Descendants(ns + "entry")
            ...

Namespace handling is beautifully easy in LINQ to XML compared with everything other XML API I've ever used :)

Upvotes: 3

Related Questions