【问题标题】:Delete multiple XML nodes in C# using Linq使用 Linq 在 C# 中删除多个 XML 节点
【发布时间】:2016-03-02 09:13:04
【问题描述】:

我正在尝试删除特定 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>

我的代码如下所示:

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);

我不确定我哪里出错了。

【问题讨论】:

  • 在尝试从 XML 文件中加载 xdoc 后是否可能为空?
  • 对不起,我的意思是属性。
  • 您确定没有没有Path 属性的任何DIR 元素吗?这肯定会导致问题...另请注意,您可以在返回一系列元素的查询上调用Remove(),然后它将全部删除:)
  • 不是确实是规范问题的副本。异常以一种非常不明显的方式在框架代码中引发。普通的诊断没有帮助。

标签: c# .net xml linq


【解决方案1】:

我不确定您为什么会收到异常,但我强烈怀疑这是因为您在查询时修改了文档。

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

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

但是,这不是最好的方法。最好的方法是使用Remove(this IEnumerable&lt;XElement&gt;) extension method

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

根本不需要foreach 循环。现在,为了使其在面对没有 Path 属性的 DIR 元素时更加健壮,您可以改为转换为字符串:

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

【讨论】:

  • 感谢 Jon,在查询末尾添加 .Remove() 并将其从 for 循环中删除,修复了它我怀疑您的权利,即我在查询时尝试修改文档。添加了??处理空值。感谢您的帮助...
猜你喜欢
  • 1970-01-01
  • 2020-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多