c# linq to xml update all descendants of specific value

599 views Asked by At

I am creating a configuration file editor, and am currently implementing features for updating existing data. I would like to be able to update all attributes within the file which have a specific attribute, such as updating a user name.

My XML file represents users in the following manner:

<user user="user1" ... />
<user user="user2" ... />

My present attempt looks like this:

 xdoc.Descendants().Where(a => a.Attribute("user").Value == UserEditInput).FirstOrDefault().SetAttributeValue("user", NewUser);

where UserEditInput is the name of the current user name and NewUser is the new replacement value.

This throws a NullReferenceException. There are a number of "user" XAttributes in the form shown above with a value equal to that of UserEditInput. This leads me to believe I am not referencing the desired data in the correct manner, not modifying the attributes correctly, or both.

Thank you in advance for any assistance.

1

There are 1 answers

4
Jon Skeet On BEST ANSWER

Currently you're trying to fetch the value for the user attribute of every element in the document - including the root element, for example.

Two options here, which I'd probably use both of:

  • Specify that you only want user elements, using xdoc.Descendants("user")
  • Use a cast of XAttribute to string instead of the Value property; that way if there's no such attribute, the cast will return null as well

Additionally, if you don't find the matching element, you're using FirstOrDefault so you'll get a value of null - but you try to set the attribute value anyway. Don't do that.

So, putting it all together - and taking a short cut by using the overload of FirstOrDefault with a predicate:

var element = xdoc.Descendants("user")
                  .FirstOrDefault(a => (string) a.Attribute("user") == UserEditInput);

if (element != null)
{
    element.SetAttributeValue("user", NewUser);
}