Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to ignore a specific with a LINQ where clause?

Tags:

c#

linq

I have a client that sends an xml feed which I parse using the following code. This code works.

reviews = from item in xmlDoc.Descendants("node")
                          select new ForewordReview()
                          {
                              PubDate = (string)item.Element("created"),
                              Isbn = (string)item.Element("isbn"),
                              Summary = (string)item.Element("review")
                          };

After getting all my "reviews" I cast the IEnumerable as a List and return it out. Originally, I was having a good and easy time parsing their XML which used to look like this:

<reviews>
    <node>
        <created>01-01-1900</created>
        <ISBN>12345657890123</ISBN>
        <Review>This is a nice and silly book</Review>
    </node>
    <node>
        <created>01-01-2011</created>
        <ISBN>1236245234554</ISBN>
        <Review>This is a stupid book</Review>
    </node>
    <node>
        <created>12-06-1942</created>
        <ISBN>1234543234577</ISBN>
        <Review>This is a old, naughty book</Review>
    </node>
</reviews>

They have, however, changed their schema, to which I don't have access, and now their XML is adding in a final <node> tag to the end which does not contain the decedent elements I am looking for, and so, my parsing breaks on this last tag and I throw an exception. Here is an example:

<reviews>
    <node>
        <created>01-01-1900</created>
        <ISBN>12345657890123</ISBN>
        <Review>This is a nice and silly book</Review>
    </node>
    <node>
        <created>01-01-2011</created>
        <ISBN>1236245234554</ISBN>
        <Review>This is a stupid book</Review>
    </node>
    <node>
        <created>12-06-1942</created>
        <ISBN>1234543234577</ISBN>
        <Review>This is a old, naughty book</Review>
    </node>
    <node>
        <count>4656</count>
    </node>
</reviews>

I need to know if there is a way to ignore this final tag (its always at the end of the document) even though it has the same name as all the other "node" tags I am looking for. I do have a try catch around this block of code but it doesnt return the list of good reviews out if it sees this error.

Thanks guys.

like image 262
Isaiah Nelson Avatar asked Feb 06 '12 20:02

Isaiah Nelson


2 Answers

If it's always the last node,

var nodes = xmlDoc.Descendants("node");
reviews = nodes.Take(nodes.Count() - 1).Select(...);
like image 75
Matti Virkkunen Avatar answered Sep 26 '22 02:09

Matti Virkkunen


Something like this should do the trick:

var reviews = from item in xmlDoc.Descendants("node").Where(x => x.Element("created") != null)
select new
{
    PubDate = (string)item.Element("created"),
    Isbn = (string)item.Element("isbn"),
    Summary = (string)item.Element("review")
};

You can additional null checks for the other elements if you wish.

like image 40
MrDustpan Avatar answered Sep 26 '22 02:09

MrDustpan