有没有办法创建一个Linq XElement迭代器,在修改树时更新?

时间:2009-01-19 01:07:32

标签: c# xml linq

我是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文档类是否有一种迭代方法,随着树的更改而更新?

1 个答案:

答案 0 :(得分:2)

通常,在更改集合时,枚举器无法继续运行。但是,如果对它们使用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();
   }
}