如何从XElement中删除特定的节点?

15

我创建了一个包含下面XML的节点的XElement。

如果"Rule"节点中包含"conditions"节点,我想删除所有这样的节点。

我创建了以下循环,但它没有删除我的节点。

foreach (XElement xx in xRelation.Elements())
{
  if (xx.Element("Conditions") != null)
  {
    xx.Remove();
  }
}

示例:

<Rules effectNode="2" attribute="ability" iteration="1">
    <Rule cause="Cause1" effect="I">
      <Conditions>
        <Condition node="1" type="Internal" />
      </Conditions>
    </Rule>
    <Rule cause="cause2" effect="I">
      <Conditions>
        <Condition node="1" type="External" />
      </Conditions>
    </Rule>
</Rules>

如果"Rule"节点包含"conditions"节点,我该如何删除所有这样的节点?


你不能在删除元素时使用foreach迭代规则元素。相反,你可以将它们收集到一个列表中,然后使用for循环进行迭代并删除它们。 - Rohit Prakash
6个回答

18

你可以尝试这种方法:

var nodes = xRelation.Elements().Where(x => x.Element("Conditions") != null).ToList();

foreach(var node in nodes)
    node.Remove();

基本思路:你不能删除你当前正在迭代的集合中的元素。
因此,首先你需要创建要删除的节点列表,然后再删除这些节点。


13

你可以使用 Linq:

xRelation.Elements()
     .Where(el => el.Elements("Conditions") == null)
     .Remove();

或者创建要删除节点的副本,然后在之后删除它们(以防第一种方法不起作用):

List nodesToDelete = xRelation.Elements().Where(el => el.Elements("Conditions") == null).ToList();

foreach (XElement el in nodesToDeletes)
{
    // Removes from its parent, but not nodesToDelete, so we can use foreach here
    el.Remove();
}

我认为你在顶部的解决方案行不通。el.Elements("Conditions") == null) 总是会被评估为非空。 - Ciaran Gallagher
@CiaranGallagher 嗯,这个答案已经有7年了,但是它被点赞了12次,所以我认为在当时它是一个解决 OP 问题的有效方法 :) - Kilazur

3
  passiveLead.DataXml.Descendants("Conditions").Remove();

这将从XML文档中删除所有名称为“Conditions”的descendant元素。


3
你能否为原帖作者和未来的读者添加一些额外的解释或参考资料? - Ryan Gates

2
我为您制作了一个小的示例:

我为您准备了一个小例子:

XDocument document = XDocument.Parse(GetXml());
var rulesNode = document.Element("Rules");
if (rulesNode != null)
{
    rulesNode.Elements("Rule").Where(r => r.Element("Conditions") != null).Remove();
}

1
var el = xRelation.XPathSelectElement("/Rules/Rule/Conditions");
while (el != null)
{
      el.Remove();
      el = xRelation.XPathSelectElement("/Rules/Rule/Conditions");
}

-1

仅仅是一个想法:

反转Linq的“条件”,你就可以得到一个没有“规则”节点的列表


你好!小的回答请放在评论区。请等到您有足够的声望才能进行评论。请参阅https://stackoverflow.com/help/how-to-answer。 - Ankur Aggarwal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接