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.
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();
See more on this question at Stackoverflow