2016-03-02 12 views
5

Tôi đang cố gắng xóa nhiều nút mà một số element(path) cụ thể chứa một giá trị nhưng tôi nhận được System.NullReferenceException bất kỳ trợ giúp nào mà tôi đang gặp trục trặc mà tôi sẽ đánh giá cao.C# linq xóa nhiều nút

xml của tôi trông như thế này:

<?xml version="1.0" encoding="utf-8" standalone="yes"?> 
<ApplicationData Version="12.5.1" RootPath="FireFox-FILES"> 
    <RegistrySystem> 
    <DIR Operation="+" Path="C:\Temp\Microsoft\MediaPlayer\ShimInclusionList" /> 
    <DIR Operation="+" Path="C:\Temp\MediaPlayer\ShimInclusionList\MM.EXE" /> 
    <DIR Operation="+" Path="C:\Temp\MediaPlayer\ShimInclusionList\plugin-container.exe" /> 
    <DIR Operation="+" Path="C:\Temp\Microsoft\MediaPlayer"> 
     <ENTRY Name="" Value="43.0.4" Type="1" /> 
     <ENTRY Name="CurrentVersion" Value="43.0.4 (x86 en-GB)" Type="1" /> 
    </DIR> 
    <DIR Operation="+" Path="C:\Program Files\Microsoft\MediaPlayer\ShimInclusionList\plugin-container.exe" /> 
    <DIR Operation="+" Path="C:\Program Files\Microsoft\MediaPlayer\ShimInclusionList2\plugin.exe" /> 
    <DIR Operation="+" Path="C:\Program Files\Microsoft\MediaPlayer\ShimInclusionList2\container.exe" /> 
    <DIR Operation="+" Path="C:\Program Files\Microsoft\MediaPlayer\ShimInclusionList4"> 
     <ENTRY Name="" Value="43.0.4" Type="1" /> 
     <ENTRY Name="CurrentVersion" Value="43.0.4 (x86 en-GB)" Type="1" /> 
    </DIR> 
    </RegistrySystem> 
</ApplicationData> 

Mã của tôi trông như thế này:

XDocument xdoc = XDocument.Load(XmlFile); 
foreach (var node in xdoc.Descendants("DIR").Where(status => status.Attribute("Path").Value.Contains(@"C:\Temp\"))) 
{ 
    node.Remove(); 

} 
xdoc.Save(XmlFile); 

Tôi không chắc chắn nơi tôi sẽ sai.

+5

[gì là một 'NullReferenceException' và làm thế nào để sửa chữa nó?] (Http: // stackoverflow .com/q/4660142/447156) –

+0

Có thể 'xdoc' là null sau khi thử tải nó từ tệp XML không? – Codor

+0

Xin lỗi, tôi có nghĩa là Thuộc tính. – BillyDay

Trả lời

6

Tôi không chắc chắn lý do bạn nhận được ngoại lệ, nhưng tôi thực sự nghi ngờ đó là vì bạn đang sửa đổi tài liệu trong khi bạn đang truy vấn tài liệu.

Nếu bạn thay đổi mã của bạn để sử dụng một cuộc gọi ToList() để có được danh sách các nút để loại bỏ, điều đó không ném:

foreach (var node in xdoc.Descendants("DIR") 
      .Where(status => status.Attribute("Path").Value.Contains(@"C:\Temp\")) 
      .ToList()) 
{                    
    node.Remove(); 
} 

Tuy nhiên, đó không phải là cách tốt nhất. Phương pháp tốt nhất là sử dụng Remove(this IEnumerable<XElement>) extension method:

xdoc.Descendants("DIR") 
    .Where(status => status.Attribute("Path").Value.Contains(@"C:\Temp\")) 
    .Remove(); 

Không cần cho một vòng lặp foreach ở tất cả. Bây giờ để làm cho nó mạnh mẽ khi đối mặt với DIR yếu tố mà không có một thuộc tính Path, bạn có thể cast vào chuỗi thay vì:

xdoc.Descendants("DIR") 
    .Where(status => ((string) status.Attribute("Path") ?? "").Contains(@"C:\Temp\")) 
    .Remove(); 
+0

Cảm ơn Jon, thêm .Remove() vào cuối truy vấn và loại bỏ nó ra cho vòng lặp cố định nó tôi nghi ngờ quyền của bạn mà tôi đã cố gắng để sửa đổi các tài liệu trong khi truy vấn nó. thêm vào ?? để xử lý giá trị null. Cảm ơn bạn đã giúp đỡ... – BillyDay