5

I'm trying to remove multiple nodes that a particular element(path) contains a value but I'm receiving a System.NullReferenceException any help where I'm going wrong would I'be much appreciated.

My xml looks like this:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<ApplicationData Version="12.5.1" RootPath="FireFox-FILES">
  <RegistrySystem>
    <DIR Operation="+" Path="C:\Temp\Microsoft\MediaPlayer\ShimInclusionList" />
    <DIR Operation="+" Path="C:\Temp\MediaPlayer\ShimInclusionList\MM.EXE" />
    <DIR Operation="+" Path="C:\Temp\MediaPlayer\ShimInclusionList\plugin-container.exe" />
    <DIR Operation="+" Path="C:\Temp\Microsoft\MediaPlayer">
      <ENTRY Name="" Value="43.0.4" Type="1" />
      <ENTRY Name="CurrentVersion" Value="43.0.4 (x86 en-GB)" Type="1" />
    </DIR>
    <DIR Operation="+" Path="C:\Program Files\Microsoft\MediaPlayer\ShimInclusionList\plugin-container.exe" />
    <DIR Operation="+" Path="C:\Program Files\Microsoft\MediaPlayer\ShimInclusionList2\plugin.exe" />
    <DIR Operation="+" Path="C:\Program Files\Microsoft\MediaPlayer\ShimInclusionList2\container.exe" />
    <DIR Operation="+" Path="C:\Program Files\Microsoft\MediaPlayer\ShimInclusionList4">
      <ENTRY Name="" Value="43.0.4" Type="1" />
      <ENTRY Name="CurrentVersion" Value="43.0.4 (x86 en-GB)" Type="1" />
    </DIR>
  </RegistrySystem>
</ApplicationData>

My code looks like this:

XDocument xdoc = XDocument.Load(XmlFile);
foreach (var node in xdoc.Descendants("DIR").Where(status => status.Attribute("Path").Value.Contains(@"C:\Temp\")))
{
    node.Remove();

}
xdoc.Save(XmlFile);

I'm not sure where I'm going wrong.

6
  • 5
    What is a NullReferenceException and how do I fix it? Commented Mar 2, 2016 at 9:13
  • Is it possible that xdoc is null after the attempt to load it from the XML file? Commented Mar 2, 2016 at 9:16
  • Sorry I mean where Attribute. Commented Mar 2, 2016 at 9:16
  • 2
    Are you sure you don't have any DIR elements without a Path attribute? That would certainly cause the problem... Also note that you can just call Remove() on a query returning a sequence of elements, and it will remove then all :) Commented Mar 2, 2016 at 9:17
  • 2
    This isn't really a duplicate of the canonical question. The exception is thrown within framework code in a very non-obvious way. The normal kind of diagnostics don't help. Commented Mar 2, 2016 at 9:22

1 Answer 1

8

I'm not sure why you're getting the exception, but I strongly suspect it's because you're modifying the document while you're querying it.

If you change your code to use a ToList() call to get the list of nodes to remove, that doesn't throw:

foreach (var node in xdoc.Descendants("DIR")
           .Where(status => status.Attribute("Path").Value.Contains(@"C:\Temp\"))
           .ToList())
{                                                                            
    node.Remove();
}

However, that's not the best way. The best approach is to use the Remove(this IEnumerable<XElement>) extension method:

xdoc.Descendants("DIR")
    .Where(status => status.Attribute("Path").Value.Contains(@"C:\Temp\"))
    .Remove();

No need for a foreach loop at all. Now to make it robust in the face of DIR elements without a Path attribute, you can cast to string instead:

xdoc.Descendants("DIR")
    .Where(status => ((string) status.Attribute("Path") ?? "").Contains(@"C:\Temp\"))
    .Remove();
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Jon, adding the .Remove() on the end of the query and removing it out the for loop fixed it i suspect your right that i was trying to modify the document while querying it. added the ?? to handle null vales aswell. Thanks for your help...

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.