2

I have a model class

public class Item
{
    public string Name {get; set;}
    public string Desc {get; set;}
}

I would query my XML document

List<Item> item = xmlDoc.Descendants()
    .Select(o => new Item { 
        Name = o.Attribute("name").Value, 
        Desc = o.Attribute("desc").Value
    }).ToList(); 

However, the attribute desc may or may not be present for each item. The above LINQ works if the attribute desc is present, but will cause an exception if not.

If it does not exist I would like for the LINQ query to just assign null to the Desc field in the new Item object. Thank you for any suggestions.

1

2 Answers 2

5

The right way to do this is with the conversion operators:

Name = (string) o.Attribute("name"),
Desc = (string) o.Attribute("desc")

why is this the preferred way? Firstly, it is easy; and secondly, it works correctly for other types:

Count = (int?) o.Attribute("count"),
When = (DateTime?) o.Attribute("when")

In particular, these also apply the correct xml encoding rules for each data type, rather than using a culture-specific DateTime.Parse / int.Parse etc. Lots of subtle things to not want to remember!

Note that if you want to assert that the attribute exists, the non-Nullable<T> versions work too:

Size = (int) o.Attribute("size"),
Created = (DateTime) o.Attribute("created")
Sign up to request clarification or add additional context in comments.

Comments

1

You can use the ternary operator - ?:

List<Item> item = xmlDoc.Descendants() 
    .Select(o => new Item {  
        Name = o.Attribute("name") != null ? o.Attribute("name").Value : null,  
        Desc = o.Attribute("desc") != null ? o.Attribute("desc").Value : null,
    }).ToList();  

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.