0

I have XElement xDoc =

<div id="item123">
    <div id="item456">
        <h3 id="1483538342">
           <span>Dessuten møtte</span> 
        </h3>
        <p>Test!</p> 
    </div>
</div>

When I try to remove en item with id = "item456" I get an error

System.NullReferenceException: Object reference not set to an instance of an object.

var item = "456";
xDoc.Descendants("div").Where(s => s.Attribute("id").Value == "item" + item).Remove();

I can't understand what is wrong here.

podeig
  • 2,597
  • 8
  • 36
  • 60

2 Answers2

2

You need to check if the current element (inside the where iteration) has an id attribute, otherwise you will access a null object and get an exception.

var item = "456";
xDoc.Descendants("div").Where(s => s.Attribute("id") != null && s.Attribute("id").Value == "item" + item).Remove();
Andrei V
  • 7,306
  • 6
  • 44
  • 64
  • It looks that you are right. I do not get the exception any more. But this element is stil there. It is not removed. – podeig Jan 14 '14 at 11:01
  • Is the element still in the `xdoc` object or are you talking about a file where it gets persisted? You can check if `Where` finds your targeted element by using `var elem = xDoc.Descendants("div").Where(s => s.Attribute("id") != null && s.Attribute("id").Value == "item" + item).FirstOrDefault();`. If `elem` is `null` your argument ("item456") might not be valid. – Andrei V Jan 14 '14 at 11:07
  • Everything is ok. Working!!! I checked the result at the wronf place. Thank you for help, Andrei! :) – podeig Jan 14 '14 at 11:14
1

Your error means that some of div elements do not have id attribute. Thus s.Attribute("id") returns null. Trying to get it's value throws exception. If you will cast attribute to string instead of trying to access it's Value, you will not get error (null will be returned if attribute was not found):

xDoc.Descendants("div")
    .Where(d => (string)d.Attribute("id") == "item" + item)
    .Remove();

Also thus you are dealing with HTML I suggest you to use appropriate tool - HtmlAgilityPack. Removing your div nodes will look like:

HtmlDocument doc = new HtmlDocument();
doc.Load(path_to_file);
foreach (var div in doc.DocumentNode.SelectNodes("//div[@id='item456']"))
    div.Remove();
Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459