1

I was trying to remove a descendant element from an XElement (using .Remove()) and I seem to get a null object reference, and I'm not sure why.

Having looked at the previous question with this title (see here), I found a way to remove it, but I still don't see why the way I tried 1st didn't work.

Can someone enlighten me ?

  String xml = "<things>"
             + "<type t='a'>"
             + "<thing id='100'/>"
             + "<thing id='200'/>"
             + "<thing id='300'/>"
             + "</type>"
             + "</things>";

  XElement bob = XElement.Parse(xml);

  // this doesn't work...
  var qry = from element in bob.Descendants()
            where element.Attribute("id").Value == "200"
            select element;
  if (qry.Count() > 0)
     qry.First().Remove();

  // ...but this does
  bob.XPathSelectElement("//thing[@id = '200']").Remove();

Thanks, Ross

2 Answers 2

3

The problem is that the collection you are iterating contains some element that don't have the id attribute. For them, element.Attribute("id") is null, and so trying to access the Value property throws a NullReferenceException.

One way to solve this is to use a cast instead of Value:

var qry = from element in bob.Descendants()
          where (string)element.Attribute("id") == "200"
          select element;

If an element doesn't have the id attribute, the cast will returns null, which works fine here.

And if you're doing a cast, you can just as well cast to an int?, if you want.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks svick, I see what the issue is now.
1

Try the following:

  var qry = bob.Descendants()
               .Where(el => el .Attribute("id") != null)
               .Where(el => el .Attribute("id").Value = "200")

  if (qry.Count() > 0)
     qry.First().Remove();

You need to test for the presence of the id attribute before getting its value.

3 Comments

Thanks for the useful advice re. checking attributes - I see why its relevant in the light of svick's answer.
@BlackLight oh well, it was worth a try!
Well, no offense but it's been over three years and I'm really surprised how no body saw any errors in this code. There are 3 very noticeable mistakes. el .Attribute has white space both times and Attribute("id").Value = "200" should have been Attribute("id").Value == "200" instead. Notice the double = sign.

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.