3

这是我的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>

请指导我摆脱这个问题......

4

5 回答 5

11

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

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

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

于 2012-09-06T10:34:39.980 回答
3

Chris 解释说,迭代失败是因为您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
于 2013-05-10T21:26:50.313 回答
3

问题是你正在改变你在这些行中迭代的东西:

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

yyNode.ParentNode如果您要替换为,这更容易发现xxNode(保证是这样)。这会导致迭代器感到困惑并跳过一些你不希望它做的事情。

可能更容易虽然只是打电话xxNode.RemoveAll()。请参阅文档:http: //msdn.microsoft.com/en-us/library/system.xml.xmlnode.removeall

但是请注意,正如 Mahen 所说,这也会删除您的属性,因此通常不是所需的解决方案(例如,在这种情况下不是)。

于 2012-09-06T10:34:55.683 回答
2

代码没有问题,您只需要准确地使用您的文字即可。它们区分大小写。写“page”而不是“PAGE”和“Paragraph”而不是“PARAGRAPH”,那么代码就可以正常工作了。

于 2012-09-06T10:37:35.607 回答
0
while (parentNode.ChildNodes.Count > 0) 
{
   parentNode.RemoveChild(parentNode.ChildNodes[0]);
}

也应该工作。

于 2022-01-29T04:12:27.663 回答