c# linq to xml update all descendants of specific value

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.

Jon Skeet
people
quotationmark

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);
}

people

See more on this question at Stackoverflow