2016-02-02 19 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"));