【问题标题】:how to remove Xelement without its children node using LINQ?如何使用 LINQ 删除没有子节点的 Xelement?
【发布时间】:2014-02-12 14:09:01
【问题描述】:

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

我正在使用以下代码删除 &lt;X&gt; 节点而不删除其血统/子节点,

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

但正在删除整个 &lt;X&gt; 块。

预期输出:

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

【问题讨论】:

    标签: c# linq linq-to-xml


    【解决方案1】:
    var x = doc.Root.Element("X");
    x.Remove();
    doc.Root.Add(x.Elements());
    

    【讨论】:

    • 我建议添加到 x 的前一个父元素。
    • ... 并且还支持多个X 元素。
    【解决方案2】:

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

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

    以下代码删除所有&lt;x&gt; 节点,将子节点保持在正确位置:

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

    【讨论】:

      【解决方案3】:

      稍微改进 Mike 的有用答案。

      您不能只迭代Descendants 一次的原因是AddAfterSelf() 创建了副本。第一次删除后,您将迭代已删除元素的子元素,而不是文档中的替换元素。

      但是,如果您向后迭代,则任何复制的子节点都将已被处理,因此您只需通过一次即可:

      foreach(var x in xdoc.Descendants("x").Reverse())
      {
          x.AddAfterSelf(x.Nodes());
          x.Remove();
      }
      

      【讨论】:

        【解决方案4】:

        如果节点名称已被弃用且不得在整个文档中使用,只需使用 ReplaceWith:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-03-27
          • 2013-02-04
          • 2020-06-27
          • 2018-11-11
          相关资源
          最近更新 更多