2016-10-12 4 views
0

나는 경우 다음과 같은 구조를 갖는 XML 파일 (예를 들어) :자식 노드 유지하는 XML 부모 노드를 제거

내가 예상 출력 listChildlistChild2을 제거 할
<Parent1> 
     <listChild> 
      <child> 
       <listchild2> 
        <child2> 
        <child2> 
        <child2> 
       </listchild2> 
      </child> 
      <child> 
       <listchild2> 
        <child2> 
        <child2> 
        <child2> 
       </listchild2> 
      </child> 
     </listchild> 
</parent1> 

:

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

이 코드는 XML로 C# 클래스를 변환 할 수 있습니다. dcuMgr, modemMgr, meterMgr 자식 노드를 지우고 싶습니다. 어떻게해야합니까?

+0

대신'listchild'를 제거하면 코드가 잘 작동합니다 .. 코드를 업데이트 할 때 어떤 문제가 있는지 잘 모르겠습니다. –

+0

개념적으로, 노드의 내용을 복사 한 다음 노드 자체를 삭제하고 부모 노드의 내용에 붙여 넣어야합니다. 이를 처리 할 수있는 함수를 만들 수 있습니까? – Khyron

답변

0

사양이 명확하지 않습니다. XML 자체에는 "목록"이라는 개념이 없습니다. 모든 요소는 여러 개의 하위 요소를 포함 할 수 있으며 XML은 요소의 이름이 무엇인지 신경 쓰지 않습니다. 요소에서 "list"라는 단어를 사용한다고해도 실제로는 목록이 아닙니다.

또한 예제 XML에서는 두 가지 종류의 "자식"노드를 보여줍니다. 외부 노드는 child이고 내부 노드는 child2입니다. 그러나 원하는 결과물에는 child이라는 이름 만 있습니다. child2 노드는 child 노드로 바뀌 었습니다.

불행히도 XML은 유효한 XML조차 아닙니다. 따라서 XML 예제를 제공하지 않았으므로 자신이하려는 일을 이해하기가 훨씬 더 어렵습니다.

모든 염두에두고, 중첩 된 객체에 동일한 알고리즘을 적용하려는 경우 원하는 기본 접근 방식은 재귀를 기반으로하는 것입니다. 나는. 유지할 노드를 재귀 적으로 선택하고 동일한 제거 논리를 적용하려고합니다. 여기

이있는 Complete, Minimal, and Verifiable code example (즉, 첫 번째 장소에서 질문에 포함되어 있어야합니다 것과 유사)이 기본 개념을 설명한다 :

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

당신이 마음에서 행동의 다른 종류가있는 경우, 당신이 실제로하고 싶은 것을 성취하기 위해 위에서 보여준 기본 기술을 적용 할 수 있어야합니다.

+0

관심을 가져 주셔서 감사합니다. 나는 영어를 거의 할 수 없다. 이해해주십시오. –

+0

내 xml 코드를 다시 작성하십시오 : –

+0

귀하의 편집은별로 명확히 밝히지 않았습니다. XML은 올바른 형식이 아니며'DcuManager' 노드를 없애고 루트 노드라는 이전 예제를 기반으로한다고 가정하기 때문에 루트 노드를 제거하는 방법을 알지 못합니다. 또한 보존하려는 노드에서 제거/전개하려는 노드를 구별하는 것이 명확하지 않습니다. 이름에 "list"가 포함 된 새 XML 예제의 노드가 있더라도 해당 노드를 제거하지 않으려하지 않는 것 같습니다. 위의 내용이 당신을 가장 중요하게 생각한다고 생각하지만, 여전히 도움이 필요하면 질문을 많이 개선해야합니다. –

관련 문제