【问题标题】:Is there a way to create an Linq XElement iterator that is updated as the tree is modified?有没有办法创建一个随着树被修改而更新的 Linq XElement 迭代器?
【发布时间】:2009-01-19 01:07:32
【问题描述】:

我是 C# 和 Linq 的新手。我正在尝试使用 Linq 生成的元素集合来迭代和修改 XDocument 中的某些元素。我的理解是树更新时枚举不会更新。

例如,给定文档

<root xmlns:ns="http://dummy">
<ns:a/>
<ns:b/>
<c/>
<ns:a><ns:a/></ns:a>
</root>

和代码

XDocument doc = XDocument.Load(@"test_input.xml", LoadOptions.PreserveWhitespace);
XNamespace ns = "http://dummy";

IEnumerable<XElement> elem_list = from elem in doc.Descendants()
                                  where elem.Name.Namespace == ns
                                  select elem;

foreach (XElement elem in elem_list) {
   if (elem.Name.LocalName == "a") {
      elem.Remove();
   }
}

给出错误,因为(我认为)嵌套的“a”元素已从树中删除,但仍“存在”在 elem_list 中。

我该如何解决这个问题,请记住 (1) 我想要执行的实际操作涉及比上述示例更复杂的树操作(即复制),以及 (2) 我正在工作带有大量空白的混合内容?其他 .Net XML 文档类是否有一种迭代方式,随着树的变化而更新?

【问题讨论】:

    标签: c# xml linq


    【解决方案1】:

    通常,当集合更改时,枚举器无法继续运行。但是,如果您在它们上使用ToArray() 或ToList(),则整个结果集合将位于静态列表中。然后,您可以对列表进行枚举,并且将它们(从文档中,而不是从列表中)删除并不重要。

    XDocument doc = XDocument.Load(@"test_input.xml", LoadOptions.PreserveWhitespace);
    XNamespace ns = "http://dummy";
    
    IEnumerable<XElement> elem_list = from elem in doc.Descendants()
                                      where elem.Name.Namespace == ns
                                      select elem;
    
    XElement[] elem_array = elem_list.ToArray();
    
    foreach (XElement elem in elem_array) {
       if (elem.Name.LocalName == "a") {
          elem.Remove();
       }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-15
      • 2021-10-16
      • 1970-01-01
      相关资源
      最近更新 更多