.net 如何在C#4.0中删除指定xmlnode的所有子节点?

f45qwnt8  于 2023-02-01  发布在  .NET
关注(0)|答案(6)|浏览(266)

这是我的xml。

<Document>
<page no="1">
  <Paragraph no="1">
    <Line>line1</Line>
  </Paragraph>
  <Paragraph no="2">
    <Line>line2</Line>
  </Paragraph>
</page>
<page no="2">
  <Paragraph no="1">
    <Line>line1</Line>
  </Paragraph>
  <Paragraph no="2">
    <Line>line2</Line>
  </Paragraph>
</page>
</Document>

我的C#代码

XmlDocument xd = new XmlDocument();
            xd.Load(@"H:\Sample-8-final.xml");
            XmlNodeList pnodelist = xd.GetElementsByTagName("page");
            XmlNodeList xdChildNodeList = xd.ChildNodes;

            for (int i = 0; i < pnodelist.Count; i++)
            {
                XmlNode pageNode = pnodelist[i];
                foreach (XmlNode xxNode in pageNode.ChildNodes)
                {
                    if (xxNode.Name.ToString().Trim().Equals("Paragraph"))
                    {
                        foreach (XmlNode yyNode in xxNode.ChildNodes)
                        {
                            yyNode.ParentNode.RemoveChild(yyNode);
                        }
                    }
                }
                xd.Save(@"H:\Sample-8-final_1.xml");

我的必需输出为

<Document>
<page no="1">
  <Paragraph no="1">
  </Paragraph>
  <Paragraph no="2">
  </Paragraph>
</page>
<page no="2">
  <Paragraph no="1">
  </Paragraph>
  <Paragraph no="2">
  </Paragraph>
</page>
</Document>

但我的代码产生了错误的结果如下:

<Document>
    <page no="1">
      <Paragraph no="1">
      </Paragraph>
      <Paragraph no="2">
        <Line>line2</Line>
      </Paragraph>
    </page>
    <page no="2">
      <Paragraph no="1">
      </Paragraph>
      <Paragraph no="2">
        <Line>line2</Line>
      </Paragraph>
    </page>
    </Document>

请引导我走出这个问题...

de90aj5v

de90aj5v1#

使用LINQ to XML删除Paragraph元素的所有后代:

XElement root = XElement.Load(@"H:\Sample-8-final_1.xml");
root.Descendants("Paragraph").Descendants().Remove();

注意:您需要将using System.Xml.Linq;放在文件的顶部。

7xllpg7q

7xllpg7q2#

Chris explained,迭代失败是因为在迭代该集合时修改了ChildNodes(通过删除它们)。他建议改用RemoveAll()。但是RemoveAll()删除了属性和子元素,这不是我想要的。因此,我编写了以下代码,以便在保留属性的同时安全地进行迭代(在VB.NET中):

Private Shared Sub RemoveAllChildren(element As XmlElement)
    ' you can't iterate and delete in the same loop, because you would be modifying .ChildNodes
    Dim childrenList = New ArrayList()
    For Each child In element.ChildNodes
        childrenList.Add(child)
    Next
    For Each child In childrenList
        child.ParentNode.RemoveChild(child)
    Next
End Sub
zqdjd7g9

zqdjd7g93#

问题在于,您正在更改以下行中正在迭代的内容:

foreach (XmlNode yyNode in xxNode.ChildNodes)
{
    yyNode.ParentNode.RemoveChild(yyNode);
}

如果你用xxNode替换yyNode.ParentNode(这是肯定的),这会更容易发现,这会导致迭代器混乱,跳过一些你不想让它跳过的东西。
可能更简单的方法是调用xxNode.RemoveAll()http://msdn.microsoft.com/en-us/library/system.xml.xmlnode.removeall
然而,请注意,正如Mahen所说,这也将删除您的属性,因此通常不是理想的解决方案(例如,在这种情况下不是)。

lrpiutwd

lrpiutwd4#

这段代码没有问题,你只需要精确地使用你的文字。它们是大小写敏感的。写“page”而不是“PAGE”,写“Paragraph”而不是“PARAGRAPH”,那么代码就能正常工作。

tpgth1q7

tpgth1q75#

while (parentNode.ChildNodes.Count > 0) 
{
   parentNode.RemoveChild(parentNode.ChildNodes[0]);
}

应该也行。

pkbketx9

pkbketx96#

简单,只需在以下时间使用:

while (node.HasChildNodes)
{
    node.RemoveChild(node.FirstChild);
}

相关问题