删除没有子节点的父节点

时间:2023-03-27
本文介绍了删除没有子节点的父节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我有一个关于从 xml 文件中删除特定节点的问题.

I have a question related to removing specific nodes from xml file.

这是我的 XML 示例:

Here is my sample of XML:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <nodeA attribute="1">
    <nodeB attribute="table">
      <nodeC attribute="500"></nodeC>
      <nodeC attribute="5"></nodeC>
    </nodeB>
    <nodeB attribute="3">
      <nodeC attribute="4"></nodeC>
      <nodeC attribute="5"></nodeC>
      <nodeC attribute="5"></nodeC>
    </nodeB>
    <nodeB attribute="placeHolder">
    <nodeB attribute="toRemove">
      <nodeB attribute="glass"></nodeB>
        <nodeE attribute="7"></nodeE>
      <nodeB attribute="glass"></nodeB>
      <nodeB attribute="glass"></nodeB>
    </nodeB>
    </nodeB>
    <nodeB attribute="3">
      <nodeC attribute="4"></nodeC>
      <nodeC attribute="5"></nodeC>
      <nodeC attribtue="5"></nodeC>
     </nodeB>
    <nodeB attribute="placeHolder">
    <nodeB attribute="toRemove">
      <nodeB attribute="glass"></nodeB>
        <nodeE attribute="7"></nodeE>
      <nodeB attribute="glass"></nodeB>
      <nodeB attribute="glass"></nodeB>
    </nodeB>
    </nodeB>
  </nodeA>
</root>

我想删除节点 nodeB="toRemove" 而不删除该节点的子节点.之后我需要对 nodeB attribute="placeHolder" 做同样的事情.部分结果如下所示:

I would like to remove node nodeB="toRemove" without removing childrens of this node. After that I need to do same thing with nodeB attribute="placeHolder". Part of result would look like that:

     <nodeB attribute="3">
      <nodeC attribute="4"></nodeC>
      <nodeC attribute="5"></nodeC>
      <nodeC attribtue="5"></nodeC>
     </nodeB>
     <nodeB attribute="glass"></nodeB>
        <nodeE attribute="7"></nodeE>
     <nodeB attribute="glass"></nodeB>
     <nodeB attribute="glass"></nodeB>

我一直在尝试这样的代码来实现:

I have been trying code like this to achive that:

        XmlNodeList nodeList = doc.SelectNodes("//nodeB[@attribute="toRemove"]");

        foreach (XmlNode node in nodeList)
        {
            foreach (XmlNode child in node.ChildNodes)
            {
                node.ParentNode.AppendChild(child);
            }
            node.ParentNode.RemoveChild(node);
        }
        doc.Save(XmlFilePathSource);

我能够找到具有所需属性 toRemove 或 placeHolder 的节点,但是我无法将此节点的子节点上移一级.在这种情况下你能帮我吗?它可以是 Linq、XDocument、XmlReader 的解决方案,但我更喜欢使用 XmlDocument.感谢您提前为我提供的任何帮助.

I am able to locate node with desired attribute toRemove or placeHolder, however I am not able to move children of this nodes up by one level. Could you help me in this case? It can be solution with Linq, XDocument, XmlReader but I prefer working with XmlDocument. Thank you for any help you could provide me in advance.

在这种情况下,我使用了 Chuck Savage 在下面编写的稍微修改过的代码(以保持顺序).一次删除

In this case I have used slightly modified code(to preserve order) that Chuck Savage wrote bellow. Once to remove

  <nodeB attribute="toRemove"> </nodeB>

然后对

  <nodeB attribute="placeHolder"></nodeB>

这里是稍微修改的代码

  XElement root = XElement.Load(XmlFilePathSource); 
  var removes = root.XPathSelectElements("//nodeB[@attribute="toRemove"]");
  foreach (XElement node in removes.ToArray())
  {
    node.Parent.AddAfterSelf(node.Elements());
    node.Remove();
  }
  root.Save(XmlFilePathSource);

@MiMo 提供的 xslt 方法在这种情况下也非常有用.

xslt approach provided by @MiMo is very useful as well in this case.

推荐答案

使用 Linq-to-XML 和您的 XPath,

Using Linq-to-XML and your XPath,

XElement root = XElement.Load(XmlFilePathSource); // or .Parse(string)
var removes = root.XPathSelectElements("//nodeB[@attribute="toRemove"]");
foreach (XElement node in removes.ToArray())
{
    node.AddBeforeSelf(node.Elements());
    node.Remove();
}
root.Save(XmlFilePathSource);

注意:XPath 在 System.Xml.XPath

Note: XPath is available in System.Xml.XPath

注意 2:您可以使用 这些扩展 与 XmlDocument 进行转换,因为您更喜欢 XmlDocument.

Note2: You can convert to/from XmlDocument using these extensions since you prefer XmlDocument.

这篇关于删除没有子节点的父节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:检测 XML 的更好方法? 下一篇:使用 LINQ 解析 XML 以获取子元素

相关文章