簡體   English   中英

刪除保留子節點的XML父節點

[英]Remove an XML parent node keeping child nodes

例如,如果我有一個具有以下結構的XML文件:

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

我想刪除listChildlistChild2與預期的輸出:

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

我嘗試了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);
}

但是代碼僅刪除了外部列表。

有沒有一種方法可以僅保留<listchild></listchild>標簽,並保留其所有子節點?

------------------------更新------------------------- ------------

上面的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>

此代碼將c#類轉換為xml。 我想刪除dcuMgr,modemMgr,meterMgr並保留子節點。 我如何?

您的說明不是很清楚。 XML本身沒有“列表”的概念。 任何元素都可以包含任意數量的子元素,而XML不在乎元素的名稱是什么。 在元素中使用單詞“列表”實際上並不會使其成為列表。

此外,在示例XML中,您顯示了兩種不同的“子”節點,外部節點名為child ,內部節點名為child2 但是在所需的輸出中,您只有名字child child2節點似乎已經被替換child節點。

不幸的是,您顯示的XML甚至不是有效的XML。 因此,很明顯,您沒有為我們提供真正的 XML示例,這使您更難以理解您要做什么。

因此,考慮到所有這些,我將指出,假設要對一系列嵌套對象應用相同的算法,則要使用的基本方法是基於遞歸的方法。 也就是說,您想遞歸地選擇要保留的節點,並對其應用相同的刪除邏輯。

這是一個完整,最小和可驗證的代碼示例 (即與問題中首先應包含的內容相似),它說明了這一基本思想:

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;
    }
}

如果您有其他某種行為的想法,則應該能夠采用上面顯示的基本技術來完成您實際想要做的任何事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM