문제

나는 두 세트의 Xelements를 단일의 독특한 요소 세트로 통합해야합니다. .union () 확장 방법을 사용하여 노조 대신 "Union All"을 얻습니다. 내가 뭔가를 놓치고 있습니까?

var elements = xDocument.Descendants(w + "sdt")
                   .Union(otherDocument.Descendants(w + "sdt")
                   .Select(sdt =>
                       new XElement(
                           sdt.Element(w + "sdtPr")
                               .Element(w + "tag")
                               .Attribute(w + "val").Value,
                           GetTextFromContentControl(sdt).Trim())
                   )
               );
도움이 되었습니까?

해결책

첫 번째 충동은 거의 정확했습니다. :) 데이비드 b, 당신이 LINQ에 평등을 정의하는 방법을 정확하게 말하지 않고 많은 XELEMENTS를 제공하면 참조로 비교할 수 있습니다. 다행스럽게도 iequalitycomparer‹xelement›(기본적으로 True Iff 두 xelements를 반환하는 동등한 메소드가있는 객체는 정의에 따라 동일하고 그렇지 않으면 xlement를 취하는 gethashcode 메소드를 지정하여 다른 기준을 사용하도록 지시 할 수 있습니다. 평등 기준에 따라 해시 코드를 반환합니다).

예를 들어:

var elements = xDocument.Descendants(w + "sdt")
               .Union(otherDocument.Descendants(w + "sdt", new XElementComparer())
               .RestOfYourCode

...

프로젝트의 다른 곳

public class XElementComparer : IEqualityComparer‹XElement› {
   public bool Equals(XElement x, XElement y) {
     return ‹X and Y are equal according to your standards›;
}


 public int GetHashCode(XElement obj) {
     return ‹hash code based on whatever parameters you used to determine        
            Equals. For example, if you determine equality based on the ID 
            attribute, return the hash code of the ID attribute.›;

 }

 }

참고 : 집에 프레임 워크가 없으므로 정확한 코드가 테스트되지 않고 iequalitycomparer 코드는 여기 (두 번째 게시물로 스크롤).

다른 팁

그 결론에 도달하기 위해 당신이 무엇을 사용하고 있는지 보지 않고 "왼쪽 가입"관찰을 문제 해결하기는 정말 어렵습니다. 여기 어둠 속에서의 샷이 있습니다.

XDocument doc1 = XDocument.Parse(@"<XML><A/><C/></XML>");
XDocument doc2 = XDocument.Parse(@"<XML><B/><C/></XML>");
//
var query1 = doc1.Descendants().Union(doc2.Descendants());
Console.WriteLine(query1.Count());
foreach (XElement e in query1) Console.WriteLine("--{0}",e.Name);

6
--XML
--A
--C
--XML
--B
--C
//
var query2 = doc1.Descendants().Concat(doc2.Descendants())
  .GroupBy(x => x.Name)
  .Select(g => g.First());
Console.WriteLine(query2.Count());
foreach (XElement e in query2) Console.WriteLine("--{0}", e.Name);

4
--XML
--A
--C
--B

LINQ에서 객체 (LINQ에서 XML이 실제로있는 것)에서, 참조 유형에 대한 Union은 참조 평등을 사용하여 복제를 테스트합니다. Xlement는 참조 유형입니다.

나는 다음과 같은 일을 할 수 있었지만 매우 추악합니다.

var elements = xDocument.Descendants(w + "sdt")
                   .Concat(otherDocument.Descendants(w + "sdt")
                               .Where(e => !xDocument.Descendants(w + "sdt")
                                               .Any(x => x.Element(w + "sdtPr")
                                                             .Element(w + "tag")
                                                             .Attribute(w + "val").Value ==
                                                         e.Element(w + "sdtPr")
                                                             .Element(w + "tag")
                                                             .Attribute(w + "val").Value)))
                   .Select(sdt =>
                       new XElement(
                           sdt.Element(w + "sdtPr")
                               .Element(w + "tag")
                               .Attribute(w + "val").Value,
                           GetTextFromContentControl(sdt).Trim())
                   )
               );

확실히 더 나은 방법이 있어야합니다.

이와 같은 것은 어떻습니까?

var xDoc = from f in xDocument.Descendants(w + "sdt")
    select new {xNode = f, MatchOn = f.Element(w + "sdtPr").Element(w + "tag").Attribute(w + "val").Value };

var oDoc = from o in otherDocument.Descendants(w + "sdt")
    select new {MatchOn = o.Element(w + "sdtPr").Element(w + "tag").Attribute(w + "val").Value };

var elements = from x in xDoc.Where(f => !oDoc.Any(o => o.MatchOn == f.MatchOn))
    select new XElement(x.MatchOn, GetTextFromContentControl(x.xNode).Trim());
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top