c#linq删除多个节点

Bil*_*Day 5 .net c# xml linq

我正在尝试删除一个特定element(path)包含值的多个节点,但我收到System.NullReferenceException任何帮助,我会出错我会非常感激.

我的xml看起来像这样:

<?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>
Run Code Online (Sandbox Code Playgroud)

我的代码看起来像这样:

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);
Run Code Online (Sandbox Code Playgroud)

我不确定我哪里出错了.

Jon*_*eet 6

我不确定你为什么会得到异常,但我强烈怀疑这是因为你在查询时正在修改文档.

如果您更改代码以使用ToList()调用来获取要删除的节点列表,则不会抛出:

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

但是,这不是最好的方式.最好的方法是使用Remove(this IEnumerable<XElement>)扩展方法:

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

foreach根本不需要循环.现在为了使面对DIR没有Path属性的元素变得健壮,你可以转换为字符串:

xdoc.Descendants("DIR")
    .Where(status => ((string) status.Attribute("Path") ?? "").Contains(@"C:\Temp\"))
    .Remove();
Run Code Online (Sandbox Code Playgroud)