A better solution than element.Elements("Whatever").First()?

Posted by codeka on Stack Overflow See other posts from Stack Overflow or by codeka
Published on 2010-04-18T11:18:02Z Indexed on 2010/04/18 11:23 UTC
Read the original article Hit count: 161

Filed under:
|

I have an XML file like this:

<SiteConfig>
  <Sites>
    <Site Identifier="a" />
    <Site Identifier="b" />
    <Site Identifier="c" />
  </Sites>
</SiteConfig>

The file is user-editable, so I want to provide reasonable error message in case I can't properly parse it. I could probably write a .xsd for it, but that seems kind of overkill for a simple file.

So anyway, when querying for the list of <Site> nodes, there's a couple of ways I could do it:

var doc = XDocument.Load(...);

var siteNodes = from siteNode in 
                  doc.Element("SiteConfig").Element("SiteUrls").Elements("Sites")
                select siteNode;

But the problem with this is that if the user has not included the <SiteUrls> node (say) it'll just throw a NullReferenceException which doesn't really say much to the user about what actually went wrong.

Another possibility is just to use Elements() everywhere instead of Element(), but that doesn't always work out when coupled with calls to Attribute(), for example, in the following situation:

var siteNodes = from siteNode in 
                  doc.Elements("SiteConfig")
                     .Elements("SiteUrls")
                     .Elements("Sites")
                where siteNode.Attribute("Identifier").Value == "a"
                select siteNode;

(That is, there's no equivalent to Attributes("xxx").Value)

Is there something built-in to the framework to handle this situation a little better? What I would prefer is a version of Element() (and of Attribute() while we're at it) that throws a descriptive exception (e.g. "Looking for element <xyz> under <abc> but no such element was found") instead of returning null.

I could write my own version of Element() and Attribute() but it just seems to me like this is such a common scenario that I must be missing something...

© Stack Overflow or respective owner

Related posts about LINQ

Related posts about linq-to-xml