2016-02-02 22 views
3

合併和更新兩個XML文件我想這些簡單的XML文件合併:如何使用LINQ C#

result2.xml:

<?xml version="1.0" encoding="utf-8"?> 
<Sports> 
    <Sport id="1"> 
    </Sport> 
</Sports> 

result3.xml

<?xml version="1.0" encoding="utf-8"?> 
<Sports> 
    <Sport id="1"> 
    </Sport> 
    <Sport id="2"> 
    </Sport> 
</Sports> 

我m試着用C#代碼:

static void Main() 
{ 
    XDocument xml1 = XDocument.Load("result2.xml"); 
    XDocument xml2 = XDocument.Load("result3.xml"); 

    var combinedUnique = xml1.Descendants("Sport") 
        .Union(xml2.Descendants("Sport")); 

    foreach (var item in combinedUnique) 
    { 
    Console.WriteLine(item); 
    } 
} 

我希望得到的結果是:

<?xml version="1.0" encoding="utf-8"?> 
    <Sports> 
     <Sport id="1"> 
     </Sport> 
     <Sport id="2"> 
     </Sport> 
    </Sports> 

但我得到這個:

<?xml version="1.0" encoding="utf-8"?> 
    <Sports> 
     <Sport id="1"> 
     </Sport>                       
     <Sport id="1"> 
     </Sport> 
     <Sport id="2"> 
     </Sport> 
    </Sports> 

你可以提出如何使這個C#代碼,以這種特殊情況下工作嗎? 我試過這個陣列,它正在工作 在此先感謝!

回答

2

所以,即使單元共享他們id屬性的值相同,它們仍然是不同的對象,並不會受到任何DistinctUnion僅僅是因爲某些任意屬性值等於被認爲是相等的。

如果你需要做一個「distinctBy」,你可以用下面的方式(對有問題的性質分組,然後從每個組中選擇的第一個元素):

var combinedUnique = xml1.Descendants("Sport") 
         .Concat(xml2.Descendants("Sport")) 
         .GroupBy(xe => (int)xe.Attribute("id")) 
         .Select(g => g.First()); 

請注意,我還更換UnionConcat,因爲Union完成的額外(基於集合的插入)工作對於這種情況是無效的,因此我們可以使用效率更高的Concat(union all)。

這可能是有道理的這個包裹成一個擴展方法:所以現在

public static class LinqEx 
{ 
    public static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> src, 
                Func<T, TKey> keySelector) 
    { 
     return src.GroupBy(keySelector).Select(g => g.First()); 
    } 
} 

,您可以:

var combinedUnique = xml1.Descendants("Sport") 
         .Concat(xml2.Descendants("Sport")) 
         .DistinctBy(xe => (int)xe.Attribute("id"));