如何使用LINQ删除没有子节点的Xelement?

时间:2014-02-12 14:09:01

标签: c# linq linq-to-xml

这是我的XML

<A>
    <B  id="ABC">
      <C name="A" />
      <C name="B" />     
    </B>
    <X>
     <B id="ZYZ">
      <C name="A" />
      <C name="B" />
     </B>
    </X>
</A>

我正在使用以下代码删除 <X> 节点而不删除其下降/子节点,

XDocument doc = XDocument.Load("D:\\parsedXml.xml");
doc.Descendants("A").Descendants("X").Remove();

但是要删除整个 <X> 阻止。

预期输出:

<A>
    <B  id="ABC">
      <C name="A" />
      <C name="B" />     
    </B>
     <B id="ZYZ">
      <C name="A" />
      <C name="B" />
     </B>
</A>

4 个答案:

答案 0 :(得分:5)

var x = doc.Root.Element("X");
x.Remove();
doc.Root.Add(x.Elements());

答案 1 :(得分:3)

批准的答案将始终将子项添加到文档的末尾。如果您需要删除文档中间的条目并将孩子放在他们所在的位置,请执行以下操作:

x.AddAfterSelf(x.Nodes());
x.Remove();

以下代码会移除所有<x>个节点,让孩子们保持在正确的位置:

while (doc.Descendants("x").Count() > 0)
{
    var x = doc.Descendants("x").First();
    x.AddAfterSelf(x.Nodes());
    x.Remove();
}

答案 2 :(得分:0)

稍微改善Mike的有用答案。

不能一次迭代creation的原因是因为Descendants创建了副本。第一次删除后,您要迭代已删除元素的子项,而不是在文档中对其进行替换。

但是,如果您向后对其进行迭代,则所有已复制的子代都将已得到处理,因此您只需一次通行证即可

AddAfterSelf()

答案 3 :(得分:0)

如果不建议使用节点名称,并且不能在整个文档中使用,请使用ReplaceWith:

var xNode = doc.Descendants("x");
for (int i = 0; i < xNode.Count; i++)
{
    xNode[i].ReplaceWith(xNode[i].Nodes());
}