0
votes

I'm trying to parse google calendar events from this url: http://www.google.com/calendar/feeds/amchamlva%40gmail.com/public/full and here is my code:

 static IEnumerable<Event> getEntryQuery(XDocument xdoc)
    {
        return from entry in xdoc.Root.Elements().Where(i => i.Name.LocalName == "entry")
               select new Event
               {
                   EventId = entry.Elements().First(i => i.Name.LocalName == "id").Value,
                   Published = DateTime.Parse(entry.Elements().First(i => i.Name.LocalName == "published").Value),
                   Title = entry.Elements().First(i => i.Name.LocalName == "title").Value,
                   Content = entry.Elements().First(i => i.Name.LocalName == "content").Value,
                   Where = entry.Elements().First(i => i.Name.LocalName == "gd:where").FirstAttribute.Value,
                   Link = entry.Elements().First(i => i.Name.LocalName == "link").Attribute("href").Value,

               };
    }

using (StreamReader httpwebStreamReader = new StreamReader(e.Result))
            {
                var results = httpwebStreamReader.ReadToEnd();

                XDocument doc = XDocument.Parse(results);

                System.Diagnostics.Debug.WriteLine(doc);

                var myFeed = getEntryQuery(doc);
                foreach (var feed in myFeed)
                {
                    System.Diagnostics.Debug.WriteLine(feed.Content);

                }

            }

and It works almost fine, except for this:

Where = entry.Elements().First(i => i.Name.LocalName == "gd:where").FirstAttribute.Value,

I got an exception probably because value it's null, actually i need to get valueString attribue value (for example 'Somewhere' in this case)

<gd:where valueString='Somewhere'/>
3

3 Answers

2
votes

'gd' looks like a namespace, take a look at how to work with xml namespaces in LINQ to XML:

http://msdn.microsoft.com/en-us/library/bb387093.aspx

http://msdn.microsoft.com/en-us/library/bb669152.aspx

Maybe try something along the lines of

XNamespace gdns = "some namespace here";
entry.Elements(gdns + "where")
2
votes

The local name of <gd:where> is just where - the gd part is the namespace alias.

Rather than using all of these First calls checking the local name, it would be much cleaner if you'd just use the right fully qualified name. For example:

XNamespace gd = "http://schemas.google.com/g/2005";
XNamespace atom = "http://www.w3.org/2005/Atom";

return from entry in xdoc.Root.Elements(gd + "entry")
       select new Event
       {
           EventId = (string) entry.Element(atom + "id"),
           Published = (DateTime) entry.Element(atom + "published"),
           Title = (string) entry.Element(atom + "title"),
           Content = (string) entry.Element(atom + "content"),
           Where = (string) entry.Element(gd + "where")
           Link = (string) entry.Element(atom + "link")
       };

(That's making educated guesses on the namespace based on some documentation. You should check this against your actual feed though.)

2
votes

thanks for your help guys, it works with this simple code:

   //Where = entry.Elements().First(i => i.Name.LocalName == "where").Value,
   Where = entry.Elements().First(i => i.Name.LocalName == "where").Attribute("valueString").Value,

later I'll try to implement your suggestions for a better code implementation ;)