XmlNode.ParentNode.RemoveChild会停止foreach

时间:2015-08-19 02:08:11

标签: c# xml foreach

我试图删除类型为"删除"的每个音符,但在达到1可删除后,foreach停止。在这种情况下,只传递test2.exe和test.exe。

这就是我的XML文件:

<folder name="bin">
    <file name="test2.exe" type="undeletable">test</file>
    <file name="test.exe" type="deletable">test</file>
    <file name="test1.exe" type="deletable">test</file>
    <file name="kernel.sys" type="undeletable">test</file>
</folder>

这就是C#:

XmlNodeList fileNodeLIst = fileNode.SelectNodes("file");
foreach(XmlNode file in fileNodeLIst) {
    if (file.Attributes["type"].Value == "undeletable") {
        TerminalSystemAddMessage("Error: Unable to delete " + file.Attributes["name"].Value);
    } else if (file.Attributes["type"].Value == "deletable") {
        file.ParentNode.RemoveChild(file);
        TerminalSystemAddMessage("Deleted: " + file.Attributes["name"].Value);
    }
}

我做错了吗? 为什么foreach循环会中断,我该如何解决?

2 个答案:

答案 0 :(得分:2)

使用&#34;用于&#34;迭代语句而不是&#34; foreach&#34;迭代语句如下面的行:

  XmlNodeList fileNodeLIst = fileNode.SelectNodes("file");
    for(int iNode = fileNodeList.Count - 1; iNode >= 0; iNode --)
      {
        XmlNode file = fileNodeLIst[iNode];
        if(file.Attributes["type"].Value == "undeletable"){
            TerminalSystemAddMessage("Error: Unable to delete " + file.Attributes["name"].Value);
        }else if(file.Attributes["type"].Value == "deletable"){
            file.ParentNode.RemoveChild(file);
            TerminalSystemAddMessage("Deleted: " + file.Attributes["name"].Value);
        }
      }
  

foreach语句为数组中的每个元素或实现System.Collections.IEnumerable或System.Collections.Generic.IEnumerable接口的对象集合重复一组嵌入式语句。 foreach语句用于迭代集合以获取所需的信息,但不能用于添加或删除源集合中的项目以避免不可预测的副作用。如果您需要在源集合中添加或删除项目,请使用for循环。   来源:https://msdn.microsoft.com/en-us/library/ttw7t8t6.aspx

答案 1 :(得分:0)

您可能会发现这种方法更清洁:

var messages =
(
    from file in fileNode.SelectNodes("file").Cast<XmlNode>()
    let deletable = file.Attributes["type"].Value == "deletable"
    let name = file.Attributes["name"].Value
    select String.Format(
        deletable
            ? "Deleted: {0}"
            : "Error: Unable to delete {0}",
        name)
).ToList();

var deletables =
(
    from file in fileNode.SelectNodes("file").Cast<XmlNode>()
    where file.Attributes["type"].Value == "deletable"
    select file
).ToList();

deletables.ForEach(file => file.ParentNode.RemoveChild(file));
messages.ForEach(message => TerminalSystemAddMessage(message));

这将节点的删除与迭代的列表分开 - 因此可以解决您遇到的问题。