2013-10-21 47 views
0

首先,我感謝大家耐心解答我的問題。 我在這裏搜索了 Why doesn't this code find any duplicates within an xml element?remove a duplicate element(with specific value) from xml using linq 和接近,但沒有得到它。爲linq和C刪除XML中的重複項#

我需要刪除XML中的重複元素。這些元素可能存在也可能不存在

XML片段如下。需要刪除重複的BuildNumber元素。

<?xml version="1.0" encoding="utf-8" standalone="yes"?> 
<ProductSessions FileID="{C7DCB747-AB3A-4222-B14B-F7A7994C212F}"> 
    <Session LicenceNumber="E2240A66AC64CB770000" SessionGuid="{20c5d49e-7442-4fd0-b612-23aa743f4bd9}" FK_FileId="{C7DCB747-AB3A-4222-B14B-F7A7994C212F}"> 
     <TimeOpened>2013/10/14 11:18:43</TimeOpened> 
     <LicenseInfo Configuration="XYZ" Description="Company Standard Config+More" DongleID="-error-no-dongle-" LicenseKey="FLEXlm Server Licence" Licensed="Company USA" FK_Sess ionGuid="{20c5d49e-7442-4fd0-b612-23aa743f4bd9}" /> 
    <ProductVersion>Product 9.0.0 NTx86-64 (build 987)</ProductVersion> 
     <BuildNumber>987</BuildNumber> 
     <ProductArchitecture>NTx86-64</ProductArchitecture> 
     <ProductVersion>9.0.0</ProductVersion> 
     <SystemInfo OperativeSystem="Microsoft Windows 8 Enterprise Edition (build 9200) 64-bit" User=" " FK_SessionGuid="{20c5d49e-7442-4fd0-b612-23aa743f4bd9}" /> 
     <ApplicationName>X</ApplicationName> 
     <TimeClosed>2013/10/14 11:42:57</TimeClosed> 
</Session> 
<Session LicenceNumber="E2240A66AC64CB770000" SessionGuid="{5682f705-baa1-46c0-a5ca- 3c6d816c94cc}" FK_FileId="{C7DCB747-AB3A-4222-B14B-F7A7994C212F}"> 
     <TimeOpened>2013/10/14 11:55:23</TimeOpened> 
     <LicenseInfo Configuration="XYZ" Description="Company Standard Config+More" DongleID="-error-no-dongle-" LicenseKey="FLEXlm Server Licence" Licensed="Company USA" FK_SessionGuid="{5682f705-baa1-46c0-a5ca-3c6d816c94cc}" /> 
     <ProductVersion>Product 8.2.x NTx86-64 (build 123)</ProductVersion> 
     <BuildNumber>123</BuildNumber> 
     <BuildNumber>123</BuildNumber> 
     <BuildNumber>123</BuildNumber> 
     <ProductArchitecture>NTx86-64</ProductArchitecture> 
     <ProductVersion>8.2.x</ProductVersion> 
     <SystemInfo OperativeSystem="Microsoft Enterprise Edition (build 9200) 64-bit" User=" " FK_SessionGuid="{5682f705-baa1-46c0-a5ca-3c6d816c94cc}" /> 
     <ApplicationName>X</ApplicationName> 
     <TimeClosed>2013/10/14 11:58:20</TimeClosed> 
    </Session> 

}

我的代碼如下

// This gets the correct # of sessions 
IEnumerable<XElement> childElements = 
from element in XmlFile.Elements().Descendants("Session") 
select element; 
foreach (XElement el in childElements) 
{ 
var dups = XmlFile.Descendants(el.n).GroupBy(e =>  e.Descendants("BuildNumber").First().ToString()); 
//remove the duplicates 
foreach (XElement ele in dups.SelectMany(g => g.Skip(1))) 
ele.Remove(); 

任何人都可以點我在正確的方向?

回答

0
XmlFile.Descendants("Session") 
     .SelectMany(s => s.Elements("BuildNumber").Skip(1)) 
     .Remove(); 

該查詢從每個會話中選擇除第一個BuldNumber元素以外的所有元素,並將其刪除。因此,只有第一個BuildNumber元素將保留在每個Session元素中。

+0

這當然,假設你只有一個*一個* BuildNumber每個會話。但是,如果允許多個BuildNumber,只要它們具有不同的值... –

+0

嗨 - 非常感謝。這是在我用於調試的控制檯應用程序中工作的。我正試圖使它現在在SSIS中工作,並出於某種原因遇到了一些問題。 –

+0

@LeviCalhoun你有什麼樣的問題? –

2
var xDoc = XDocument.Load("Input.xml"); 

var duplicates = xDoc.Root 
        .Elements("Session") 
        .SelectMany(s => s.Elements("BuildNumber") 
             .GroupBy(b => (int)b) 
             .SelectMany(g => g.Skip(1))) 
        .ToList(); 

foreach (var item in duplicates) 
    item.Remove(); 

或者用IEnumerable<XNode>.Remove()擴展方法:

xDoc.Root.Elements("Session") 
     .SelectMany(s => s.Elements("BuildNumber") 
          .GroupBy(b => (int)b) 
          .SelectMany(g => g.Skip(1))).Remove(); 
+0

感謝您花時間回覆。我很欣賞它,認真。上午我必須完成某件事情 –