C# XmlNode.ParentNode.RemoveChild停止foreach

C# XmlNode.ParentNode.RemoveChild停止foreach,c#,xml,foreach,C#,Xml,Foreach,我试图用typedeletable删除每个便笺,但是在它达到1个deletable之后,foreach停止。在这种情况下,只传递test2.exe和test.exe 这就是我的XML文件的外观: <folder name="bin"> <file name="test2.exe" type="undeletable">test</file> <file name="test.exe" type="deletable">test<

我试图用typedeletable删除每个便笺,但是在它达到1个deletable之后,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>

我做错什么了吗?foreach循环为什么会中断?我如何修复它?

使用foreach迭代语句而不是foreach迭代语句,如下所示:

  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循环。 资料来源:


您可能会发现这种方法更干净:

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

这将删除节点与遍历列表分离开来,从而停止您遇到的问题。

修改您的代码以便我可以实际运行它,我发现它工作得很好。请提供可靠的复制问题。我发布的内容运行不正常。当一个deletable被传递时,它会停止foreach。我毫不怀疑在您的场景中它会失败。否则你就不会发布这个问题了。但是您没有提供任何其他人都可以不经修改地运行的代码示例。如果没有这一点,就根本不清楚代码中的错误。我在没有修改的情况下复制/粘贴了您发布的代码,但是当然,为了运行任何东西,我必须添加其他代码。当我这么做的时候,结果很好。请阅读并理解我提供的链接,以便了解需要什么样的代码示例。首先,SelectNodes返回的集合不是实际的DOM集合。因此,可以在foreach中修改DOM集合。第二,请不要使用代码片段发布C代码。只需发布代码。注意:将节点列表从最后一个遍历到第一个。@Peter Duniho,谢谢你的注释。为什么StackOverflow上没有c代码段支持?@teunissentefan,如果有帮助,请标记我的答案。谢谢。为什么StackOverflow上没有c代码段支持同样的原因是,其他语言也不支持代码片段:没有人实现它,很可能是因为这样做并不实际。Web代码是一个东西——你保证在浏览器上下文中呈现——但是任意C、java、C++、Pascal、Python、Perl、艾达等等都不能全面处理。
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));