2013-04-19 2 views
0

XML 파일의 모든 노드를 수신하는 Linq 문을 작성했습니다.Linq XML - 부모 노드와 자식 노드의 조합으로 고유 값 얻기

foreach (var node in epaXmlLoad.Root.Descendants() 
            .DescendantNodes() 
            .OfType<XElement>() 
            .Distinct()) 
{ 
    newEntity = true; 
    xmlModel.Node = node.Name.ToString(); 
    xmlModel.ParentNode = node.Parent.Name.ToString(); 

    model.Save(xmlModel); 
} 

이렇게하면 노드와 해당 노드의 부모가 테이블에 저장됩니다.

그러나 이것을 실행할 때 테이블에 중복 된 데이터가 있습니다. I 같은 이름이지만 다른 상위 노드가있는 자식 노드가 더 많기 때문에 노드 값에서 구분할 수 없습니다.

<EPC> 
<General> 
    <Input>3</Invoer> 
    <Amount>3</Amount> 
    <Name>Bla</Name> 
</General> 
<Sectors> 
    <Sector> 
     <Name>Blalbla</Perc> 
     <UsageID>0</UsageID> 
     <Detection>0</Detection> 
    <Sector> 
    <Sector> 
     <Name>Blalbla</Perc> 
     <UsageID>0</UsageID> 
     <Detection>0</Detection> 
    <Sector> 
<Sectors> 
<Devices> 
    <Device> 
     <Name>Bladiebla</name> 
     <Amount>5</Amount> 
     <Detection>True</Detection> 
    </Device> 
    <Device> 
     <Name>Bladiebla2</name> 
     <Amount>5</Amount> 
     <Detection>True</Detection> 
    </Device> 
<Devices> 
는 ^이 XML 내 문제에 대해 설명합니다.

+0

** xml ** 예제와 원하는 결과를 제공 할 수 있습니까? –

+0

질문에 – Koen

+0

을 추가했습니다. 그리고 원하는 출력은 무엇입니까? –

답변

0

예상되는 결과에 대한 질문이 명확하지 않지만 XML에서 중복 노드를 제거하려고하는 것 같습니다.

는 XML이 전체 트리의 재귀 비교를 필요로

<Parent> 
    <Child> 
    <Value>42</Value> 
    </Child> 
    <Child> 
    <Value>stackoverflow</Value> 
    </Child> 
    <Child> 
    <Value>stackoverflow</Value> 
    <Grandchild>17</Grandchild> 
    </Child> 
</Parent> 

:

<Parent> 
    <Child> 
    <Value>42</Value> 
    </Child> 
    <Child> 
    <Value>stackoverflow</Value> 
    </Child> 
    <Child> 
    <Value>stackoverflow</Value> 
    <Grandchild>17</Grandchild> 
    </Child> 
    <Child> 
    <Value>42</Value> 
    </Child> 
</Parent> 

는로 변환해야합니다. 요소에 대해 Distinct을 사용하면 하위 요소를 고려하지 않으므로 실패합니다. 별개의 요소와 새로운 XElement을 구축 할 것이다 XDocument의 루트에 Reduce를 호출

public static XElement Reduce(XElement root) 
{ 
    XElement result = new XElement(root.Name); 
    result.Add(root.Nodes().OfType<XText>()); 

    List<XElement> children = new List<XElement>(); 

    foreach (var child in root.Elements()) 
    { 
     var reducedChild = Reduce(child); 

     if (!children.Any(c => IsDuplicate(c, reducedChild))) 
     { 
      children.Add(reducedChild); 
     } 
    } 

    result.Add(children); 

    return result; 
} 

public static bool IsDuplicate(XElement element1, XElement element2) 
{ 
    if (element1.Name != element2.Name || element1.Value != element2.Value) 
    { 
     return false; 
    } 

    var children1 = element1.Elements(); 
    var children2 = element2.Elements(); 

    if (children1.Count() != children2.Count()) 
    { 
     return false; 
    } 

    return children1.Zip(children2, (c1, c2) => IsDuplicate(c1, c2)).All(isDup => isDup); 
} 

. 이제 모든 노드를 모델에 추가 할 수 있습니다.

여기에는 속성을 고려하지 않음에 유의하십시오. 또한 이것이 아마도 작업을위한 가장 효율적인 알고리즘은 아님을 알아 두십시오.

현재 : 샘플 XML에 오류 (태그가 제대로 닫히지 않음)가 가득합니다.

관련 문제