简体   繁体   English

删除保留子节点的XML父节点

[英]Remove an XML parent node keeping child nodes

If I have (for example) an XML file with the following structure: 例如,如果我有一个具有以下结构的XML文件:

<Parent1>
      <listChild>
           <child>
               <listchild2>
                    <child2>
                    <child2>
                    <child2>
               </listchild2>
           </child>
           <child>
                <listchild2>
                     <child2>
                     <child2>
                     <child2>
                </listchild2>
           </child>
      </listchild>
</parent1>

I want to remove listChild and listChild2 , with the expected output: 我想删除listChildlistChild2与预期的输出:

 <Parent>
       <child>
          <child>
          <child>
          <child>
       </child>
       <child>
          <child>
          <child>
          <child>
       </child>
</parent>

I tried System.Xml.Linq , like this: 我尝试了System.Xml.Linq ,就像这样:

public void removeParentNode(String filename)
{
    XDocument xdoc = XDocument.Load(filename);

    //remove parent1 
    var child= xdoc.Descendants("child");                       
    XElement dcuManager = new XElement("parent1 ");
    parent1 .Add(child);

    XDocument xdoc1 = new XDocument(dcuManager);
}

But the code removes only the outer list. 但是代码仅删除了外部列表。

Is there a way to remove the <listchild> and </listchild> tags only, keeping all its child nodes? 有没有一种方法可以仅保留<listchild></listchild>标签,并保留其所有子节点?

------------------------update------------------------------------- ------------------------更新------------------------- ------------

above xml code is very simple example my xml code is : 上面的xml代码是一个非常简单的示例,我的xml代码是:

<?xml version="1.0" encoding="utf-8"?>
<DcuManager xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <listDcu>
    <Dcu id="dcu1 id" mode="dcu1 mode" port="dcu1 port">
      <modemMgr>
        <listModem>
          <Modem id="Modem1 id" port="modem 1 port" communicationStatus="modem 1 mode">
            <meterManager>
              <listMeter>
                <Meter id="Meter 1 id" port="Meter 1 port" mac="Meter 1 mode" />
              </listMeter>
            </meterManager>
          </Modem>
          <Modem id="Modem2 id" port="modem 2 port" communicationStatus="modem 2 mode">
            <meterManager>
              <listMeter>
                <Meter id="Meter 2 id" port="Meter 2 port" mac="Meter 2 mode" />
              </listMeter>
            </meterManager>
          </Modem>
        </listModem>
      </modemMgr>
    </Dcu>
    <Dcu id="dcu2 id" mode="dcu2 mode" port="dcu2 port">
      <modemMgr>
        <listModem>
          <Modem id="Modem3 id" port="modem 3 port" communicationStatus="modem 3 mode">
            <meterManager>
              <listMeter>
                <Meter id="Meter 3 id" port="Meter 3 port" mac="Meter 3 mode" />
              </listMeter>
            </meterManager>
          </Modem>
          <Modem id="Modem4 id" port="modem 4 port" communicationStatus="modem 4 mode">
            <meterManager>
              <listMeter>
                <Meter id="Meter 4 id" port="Meter 4 port" mac="Meter 4 mode" />
              </listMeter>
            </meterManager>
          </Modem>
        </listModem>
      </modemMgr>
    </Dcu>
    <Dcu id="dcu3 id" mode="dcu3 mode" port="dcu3 port">
      <modemMgr>
        <listModem>
          <Modem id="Modem5 id" port="modem 5 port" communicationStatus="modem 5 mode">
            <meterManager>
              <listMeter>
                <Meter id="Meter 5 id" port="Meter 5 port" mac="Meter 5 mode" />
              </listMeter>
            </meterManager>
          </Modem>
          <Modem id="Modem6 id" port="modem 6 port" communicationStatus="modem 6 mode">
            <meterManager>
              <listMeter>
                <Meter id="Meter 6 id" port="Meter 6 port" mac="Meter 6 mode" />
              </listMeter>
            </meterManager>
          </Modem>
        </listModem>
      </modemMgr>
    </Dcu>
  </listDcu>
</DcuManager>

this code is convert c# class to xml. 此代码将c#类转换为xml。 i want remove dcuMgr, modemMgr, meterMgr keeping child nodes. 我想删除dcuMgr,modemMgr,meterMgr并保留子节点。 how do i? 我如何?

Your specification is not very clear. 您的说明不是很清楚。 XML itself does not have the concept of a "list". XML本身没有“列表”的概念。 Any element can contain any number of child elements, and XML doesn't care what the name of the elements are. 任何元素都可以包含任意数量的子元素,而XML不在乎元素的名称是什么。 Using the word "list" in an element doesn't actually make it a list. 在元素中使用单词“列表”实际上并不会使其成为列表。

In addition, in your example XML you show two different kinds of "child" nodes, the outer being named child and the inner being named child2 . 此外,在示例XML中,您显示了两种不同的“子”节点,外部节点名为child ,内部节点名为child2 But in your desired output, you only have the name child . 但是在所需的输出中,您只有名字child The child2 nodes appear to have been replaced by child nodes. child2节点似乎已经被替换child节点。

Unfortunately, the XML you show isn't even valid XML. 不幸的是,您显示的XML甚至不是有效的XML。 So it's pretty obvious you have not provided us with real XML examples, making it even more difficult to understand what you're trying to do. 因此,很明显,您没有为我们提供真正的 XML示例,这使您更难以理解您要做什么。

So, with all that in mind, I'll point out that the basic approach you want, given that you want to apply the same algorithm to a series of nested objects, is one based on recursion. 因此,考虑到所有这些,我将指出,假设要对一系列嵌套对象应用相同的算法,则要使用的基本方法是基于递归的方法。 Ie you want to recursively select the nodes you'll be keeping, and apply the same removal logic to them. 也就是说,您想递归地选择要保留的节点,并对其应用相同的删除逻辑。

Here is a Complete, Minimal, and Verifiable code example (ie similar to what should have been included in the question in the first place) that illustrates this basic idea: 这是一个完整,最小和可验证的代码示例 (即与问题中首先应包含的内容相似),它说明了这一基本思想:

class Program
{
    const string _kxmlInput =
        @"<parent1>
      <listchild>
           <child>
               <listchild2>
                    <child/>
                    <child/>
                    <child/>
               </listchild2>
           </child>
           <child>
                <listchild2>
                     <child/>
                     <child/>
                     <child/>
                </listchild2>
           </child>
      </listchild>
</parent1>";

    static void Main(string[] args)
    {
        Console.WriteLine(removeParentNode(_kxmlInput));
    }

    static string removeParentNode(string xml)
    {
        StringReader reader = new StringReader(xml);

        XDocument xdoc = XDocument.Load(reader);

        //remove parent1 
        XDocument xdoc1 = new XDocument(KeepDescendants(xdoc.Root, "child"));

        StringBuilder sb = new StringBuilder();
        XmlWriterSettings settings = new XmlWriterSettings { Indent = true };

        using (XmlWriter xmlWriter = XmlWriter.Create(sb, settings))
            xdoc1.WriteTo(xmlWriter);

        return sb.ToString();
    }

    private static XElement KeepDescendants(XElement node, string descendantName)
    {
        var child = node.Descendants(descendantName).Select(c => KeepDescendants(c, descendantName));

        if (!child.Any())
        {
            return node;
        }

        XElement newParent = new XElement(node.Name);

        newParent.Add(child);

        return newParent;
    }
}

If you have some other kind of behavior in mind, you should be able to adapt the basic technique shown above to accomplish whatever it is you actually want to do. 如果您有其他某种行为的想法,则应该能够采用上面显示的基本技术来完成您实际想要做的任何事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM