5

XElements の 2 つのセットを 1 つの一意の要素セットに統合する必要があります。.Union() 拡張メソッドを使用すると、ユニオンの代わりに「すべてのユニオン」を取得できます。何か不足していますか?

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())
                   )
               );
4

4 に答える 4

4

あなたの最初のインパルスはほぼ正しかったです。:) David Bによると、LINQ に等値を定義する方法を正確に伝えず、一連の XElements を与えると、それらは参照によって比較されます。幸いなことに、IEqualityComparer‹XElement› を指定することで、異なる基準を使用するように指示できます (基本的に、2 つの XElement が定義に従って等しい場合に true を返し、そうでない場合に false を返す Equals メソッドと、XElement を受け取る 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 コードはhereからのものです(2 番目の投稿までスクロールします)。

于 2009-02-03T03:45:26.333 に答える
0

私は以下を機能させることができましたが、それはかなり醜いです:

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())
                   )
               );

確かにもっと良い方法があるはずです。

于 2009-02-02T21:26:00.827 に答える
0

このようなものはどうですか?

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());
于 2009-02-02T23:06:42.403 に答える