Hydro
Hydro

Reputation: 83

c# linq xml attribute doesn't exist

I am trying to read an xml file and get attribute but sometime this attribute doesn't exist.

When it doesn't exist, I get this error :

System.Linq.Enumerable+WhereSelectEnumerableIterator2[System.Xml.Linq.XElement,<>f__AnonymousType02[System.String,System.String]]

And :

Critical Error : System.NullReferenceException:....

My code :

string url = @"http://vigilance.meteofrance.com/data/NXFR33_LFPW_.xml";

XDocument doc = XDocument.Load(url);
var selectedBook = from r in doc.Descendants("DV")
                          .Where(r => (string)r.Attribute("dep").Value == Departement)
                           select new
                           {
                               Color = r.Attribute("coul").Value,
                               Risque = (string) r.Element("risque").Attribute("val").Value,
                           };

And the XML looks like this:

<DV dep="02" coul="1"/>
<DV dep="03" coul="3">
    <risque val="6"/>
</DV>

Does anyone have an idea ?

Upvotes: 0

Views: 743

Answers (2)

Charles Mager
Charles Mager

Reputation: 26213

The issue is that some DV elements don't have a child risque element, so in this part of your query:

Risque = (string) r.Element("risque").Attribute("val").Value

Element will return null, and you will get a null reference exception when you try to call Attribute.

You can fix this by making not going from sequence to single item until the end, and making use of the explicit conversions from elements and attributes to primitive types like string. This way, converting from attribute to string for a null attribute will just return null.

Risque = (string) r.Elements("risque").Attributes("val").SingleOrDefault()

See this fiddle for a working demo.

Upvotes: 1

jdweng
jdweng

Reputation: 34421

Try this

            XDocument doc = XDocument.Load(url);
            var selectedBook = doc.Descendants("DV")
                               .Where(r => (string)r.Attribute("dep") == Departement)
                               .Select(r => new {
                                   Color = r.Attribute("coul").Value,
                                   Risque = r.Element("risque") == null ? null : (string)r.Element("risque").Attribute("val").Value,
                               }).ToList();

Upvotes: 0

Related Questions