views:

596

answers:

1

Hi there, I was writing a generic class to read RSS feed from various source and to consolidate in one collection of object in VB.net.

Basically the function - using LINQ to XML - is working properly, but I have a problem when the RSS feed I am trying to read does not contain one of the node (as you know, many of them are optional). I would the returned value to be an empty string or nothing, but instead I get a runtime error back. I searched the web for the same problem and I found this post http://forums.asp.net/p/1351226/2762834.aspx#2762834 that apparently explain a workaround, but it does not work with my code.

I am also surprised by the little resources I am finding about this issue, so I am now wondering if I am even putting the question in the right terms...

Following you can find the code:

Dim PostsEnum = From BlogPost In XMLSource.Descendants("item")
    Order By DateTime.Parse(BlogPost.Element("pubDate").Value) Descending
    Select New Post() With {
        .Title = BlogPost.Element("title").Value,
        .Link = BlogPost.Element("link").Value,
        .Description = BlogPost.Element("description").Value,
        .AuthorText = BlogPost.Element("author").Value,
        .Category = (From tag In BlogPost.Descendants("category")
            Select cat = tag.FirstNode.ToString).ToList,
        .PubDate = DateTime.Parse(BlogPost.Element("pubDate").Value),
        .GUID = BlogPost.Element("guid").Value
     }

i tried this on http://neatlydoc.codeplex.com/Project/ProjectRss.aspx and it worked, but the following code will generate the exception:

Dim PostsEnum = From BlogPost In XMLSource.Descendants("item")
    Order By DateTime.Parse(BlogPost.Element("pubDate").Value) Descending
    Select New Post() With {
        .Title = BlogPost.Element("title").Value,
        .Link = BlogPost.Element("link").Value,
        .Description = BlogPost.Element("description").Value,
        .AuthorText = BlogPost.Element("author").Value,
        .Category = (From tag In BlogPost.Descendants("category")
             Select cat = tag.FirstNode.ToString).ToList,
        .PubDate = DateTime.Parse(BlogPost.Element("pubDate").Value),
        .GUID = BlogPost.Element("guid").Value,
        .Source = CType(BlogPost.Element("source").Value, String)
    }

Any help will be appreciated.

Thanks

Luca

+1  A: 

If you try to evaluate .Value (etc) - then yes, it will break - however, you might try casting (apols, but my example is C# - you'll have to imagine the VB):

    select new {
      Name = (string)el.Element("abc")
      ...
    }

The explicit static conversion operator accepts null nodes and returns nulls appropriately. For more complex scenarios, just test it:

      let child = el.Element("SomeChild")
      select new {
         Name = child == null ? (string)null : (string)child.Attribute("Name")
         ...
      }

Hard to be more specific without example xml/code...


Edit re your update; the problem is that you are still reading .Value; change it to:

.Source = CType(BlogPost.Element("source"), String)

There is a conversion operator from XElement to string; you don't need to look at .Value.

Marc Gravell
Thanks for your help, unfortunately casting is not helping, apparently. I have added the faulty code.Maybe I am looking for the error in the wrong place?
lucamauri
THAT simple!I probably did not paid enough attention to that.Thanks to both of you.
lucamauri