سؤال

ولست بحاجة لاتحاد مجموعتين من XElements إلى ذلك، مجموعة واحدة فريدة من العناصر. باستخدام طريقة تمديد .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())
                   )
               );
هل كانت مفيدة؟

المحلول

كان

وأول دفعة لديك الصحيح تقريبا. :) وفقا على ديفيد B ، أو إذا كنت لا تقول LINQ بالضبط كيفية تعريف المساواة وثم تعطيه حفنة من XElements، سيكون مقارنتها بالرجوع . لحسن الحظ، يمكن أن أقول لكم لاستخدام معايير مختلفة لتحديد وIEqualityComparer (أساسا، كائن يحتوي على يساوي الأسلوب الذي يعود صحيحا المنتدى اثنين XElements متساوية وفقا لتعريف وكاذبة خلاف ذلك، وأسلوب GetHashCode التي تأخذ XElement وإرجاع رمز التجزئة على أساس معايير المساواة الخاص بك).

وعلى سبيل المثال:

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 هو من <لأ href = "http://community.sgdotnet.org/forums/t/11567.aspx" يختلط = "نوفولو noreferrer"> هنا (انزل إلى آخر الثانية).

نصائح أخرى

وانه من الصعب حقا لاستكشاف الخاص المراقبة "الانضمام اليسار" دون أن يرى ما هو عليه كنت تستخدم للوصول إلى هذا الاستنتاج. وهنا قال لي طلقة في الظلام.

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 هو حقا)، الاتحاد ضد أنواع المراجع يستخدم المساواة إشارة لاختبار التكرارات. XElement هو نوع مرجع.

وكنت قادرا على الحصول على ما يلي للعمل، لكنه هو قبيح جدا:

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