Stacey
Stacey

Reputation: 141

Linq / XML - How do you handle non existing nodes?

I am trying to figure out how to handle nodes that do not exist for all of my "card" elements. I have the following linq query:

    FinalDeck = (from deck in xmlDoc.Root.Element("Cards")
                    .Elements("Card")
                    select new CardDeck
                    {
                        Name = deck.Attribute("name").Value,
                        Image = deck.Element("Image").Attribute("path").Value,
                        Usage = (int)deck.Element("Usage"),
                        Type = deck.Element("Type").Value,
                        Strength = (int)deck.Element("Ability") ?? 0
                    }).ToList();  

with the Strength item, I had read another posting that the ?? handles the null. I am getting the following error though:

Operator '??' cannot be applied to operands of type 'int' and 'int'

How do I handle this issue?

Thanks!

Upvotes: 3

Views: 655

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1500765

Rather than use the Value property, cast to string... and for the int, cast to int? instead. The user defined conversions to nullable types will return null if the source XAttribute/XElement is null:

FinalDeck = (from deck in xmlDoc.Root.Element("Cards")
                .Elements("Card")
                select new CardDeck
                {
                    Name = (string) deck.Attribute("name"),
                    Image = (string) deck.Element("Image").Attribute("path"),
                    Usage = (int?) deck.Element("Usage"),
                    Type = (string) deck.Element("Type"),
                    Strength = (int?) deck.Element("Ability") ?? 0
                }).ToList();  

Note that this won't help for the case where the Image element is missing, as then it'll try to dereference a null element to find the path attribute. Let me know if you want a workaround for that, but it'll be a bit of a pain, relatively speaking.

EDIT: You can always create an extension method for this yourself:

public static XAttribute NullSafeAttribute(this XElement element, XName name)
{
    return element == null ? null : element.Attribute(name);
}

Then call it like this:

Image = (string) deck.Element("Image").NullSafeAttribute("path"),

Upvotes: 4

Related Questions