【问题标题】:C# Linq to XML Element.Remove Code OptimizationC# Linq to XML Element.Remove 代码优化
【发布时间】:2013-09-05 17:41:42
【问题描述】:

我使用 Linq to XML 已经有一段时间了,但离它的高级用户还很远。每隔一段时间,我都会查看我的代码并说,“必须有一种更有效的方法来做到这一点”,所以我想看看 StackOverflow 的世界是否知道一种改进以下内容的方法代码。正在完成的工作是向该方法提供一个简单的List<string>,其中包含要从 XML 文件中保存的系统记录中删除的软件列表。

var xe = (from el in mainForm.xeSystemData.Elements("System")
              where el.Element("Name").Value == systemName
              select el.Element("SoftwareList"));

    foreach (string sw in softwareToRemove)
    {
        foreach (var v in xe.Elements("Software"))
        {
            if (v.Value.ToString() == sw)
            {
                v.Remove();
            }
        }
    }

这是 XML 的 sn-p 供参考:

<SoftwareList>
  <Software>IBM Client Access</Software>
  <Software>Adobe Acrobat Reader 10.1</Software>
</SoftwareList>

我一直在想,有一种更快的方法可以利用 Linq to XML 删除选择性元素,而无需创建两个 foreach 循环。

【问题讨论】:

    标签: c# xml linq


    【解决方案1】:

    我可能会这样做:

    var toRemove = new HashSet<string>(sofwareToRemove);
    
    foreach(var item in xe.Elements("Software")
                          .Where(e => toRemove.Contains(e.Value))
    {
       item.Remove();
    }
    

    这不是特定于 Linq to XML,只是使用 HashSet 而不是列表,这将整体工作量从 O(n^2) 减少到 O(n)

    【讨论】:

    • 而且,更重要的是,在我遇到的大多数情况下,使代码更整洁。
    【解决方案2】:
    var xe = (from el in mainForm.xeSystemData.Elements("System")
              where el.Element("Name").Value == systemName
              select el.Element("SoftwareList"));
    
    xe.Descendants("Software").Where(x => softwareToRemove.Contains(x.Value)).Remove();
    

    您不需要运行任何 foreach 循环,只需添加上述 LINQ 查询即可获得所需的结果。我已经测试了我的查询,它完全符合您的要求

    【讨论】:

    • void Remove&lt;T&gt;(this IEnumerable&lt;T&gt; source) 扩展方法在内部执行foreach 循环,但你是对的:这样代码看起来更干净。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多