这是我的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>
请指导我摆脱这个问题...
答案 0 :(得分:7)
使用LINQ to XML删除Paragraph元素的所有后代:
XElement root = XElement.Load(@"H:\Sample-8-final_1.xml");
root.Descendants("Paragraph").Descendants().Remove();
注意:您需要将using System.Xml.Linq;
放在文件的顶部。
答案 1 :(得分: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所说,这将删除您的属性,因此通常不是理想的解决方案(例如,不是这种情况)。
答案 2 :(得分:2)
代码没有问题,你只需要与你的文字完全一致。它们区分大小写。 写“页面”而不是“PAGE”和“段落”而不是“PARAGRAPH”然后代码工作正常。
答案 3 :(得分:2)
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