2013-06-03 29 views
12

Tôi mới dùng cả XML và C#; Tôi đang cố gắng tìm một cách để phân tích cú pháp một tệp xml đã cho hiệu quả để truy xuất các giá trị số có liên quan, dựa trên giá trị "proj_title" = heat_run hoặc bất kỳ giá trị nào khác có thể. Ví dụ, tính toán thời gian chạy thử nghiệm cụ thể (proj_end val-proj_start val).Phân tích tệp XML bằng C#?

ex.xml: 

<proj ID="2"> 
     <proj_title>heat_run</proj_title> 
     <proj_start>100</proj_start> 
     <proj_end>200</proj_end> 
</proj> 

... Chúng tôi không thể tìm kiếm theo ID proj vì giá trị này không cố định từ chạy thử đến chạy thử. Các tập tin trên là rất lớn: ~ 8mb, và có ~ 2000 thẻ w/tên proj_title. là có một cách hiệu quả để đầu tiên tìm thấy tất cả các thẻ tên w/proj_title = "heat_run", sau đó để lấy proj bắt đầu và kết thúc giá trị cho proj_title cụ thể này bằng cách sử dụng C# ??

Dưới đây là hiện mã C# của tôi:

public class parser 
{ 
    public static void Main() 
    { 
     XmlDocument xmlDoc= new XmlDocument(); 
     xmlDoc.Load("ex.xml"); 

     //~2000 tags w/ proj_title 
     //any more efficient way to just look for proj_title="heat_run" specifically? 
     XmlNodeList heat_run_nodes=xmlDoc.GetElementsByTagName("proj_title"); 
    } 
}  
+0

Tôi đã có rất nhiều may mắn với việc sử dụng XML serialization nơi bạn có thể biến XML của bạn thành các đối tượng ... [Liên kết này] (http://support.microsoft.com/kb/815813) có thể giúp bạn –

Trả lời

3

Sử dụng XDocument và sử dụng api LINQ. http://msdn.microsoft.com/en-us/library/bb387098.aspx

Nếu hiệu suất không như mong đợi sau khi thử, bạn phải tìm trình phân tích cú pháp sax. Trình phân tích cú pháp Sax sẽ không tải toàn bộ tài liệu trong bộ nhớ và thử áp dụng biểu thức xpath trên mọi thứ trong bộ nhớ. Nó hoạt động nhiều hơn trong một cách tiếp cận hướng sự kiện và trong một số trường hợp, điều này có thể nhanh hơn rất nhiều và không sử dụng nhiều bộ nhớ.

Có thể có các trình phân tích cú pháp sax cho .NET xung quanh đó, chưa sử dụng chúng cho .NET nhưng tôi đã làm cho C++.

14

8MB thực sự không phải là rất lớn ở tất cả các tiêu chuẩn hiện đại. Cá nhân tôi muốn sử dụng LINQ to XML:

XDocument doc = XDocument.Load("ex.xml"); 
var projects = doc.Descendants("proj_title") 
        .Where(x => (string) x == "heat_run") 
        .Select(x => x.Parent) // Just for simplicity 
        .Select(x => new { 
           Start = (int) x.Element("proj_start"), 
           End = (int) x.Element("proj_end") 
          }); 

foreach (var project in projects) 
{ 
    Console.WriteLine("Start: {0}; End: {1}", project.Start, project.End); 
} 

(Rõ ràng điều chỉnh này theo yêu cầu riêng của bạn - đó là không thực sự rõ ràng những gì bạn cần làm dựa trên câu hỏi.)

truy vấn Alternative:

var projects = doc.Descendants("proj") 
        .Where(x => (string) x.Element("proj_title") == "heat_run") 
        .Select(x => new { 
           Start = (int) x.Element("proj_start"), 
           End = (int) x.Element("proj_end") 
          }); 
+0

Điều này đã giúp tôi rất nhiều! Tôi chỉ cần thêm 1 địa điểm nữa. Có một tùy chọn trong LINQ/C# đề cập đến tổ tiên của x chẳng hạn? như Where (x => (string) x == "heat_run" && (string) x.Ancestor == "heat_test"). Tôi đã thử điều này, và nó đã không hoạt động? – jerryh91

+0

@ jerryh91: Vâng, bạn có thể sử dụng 'Parent', nhưng tôi thường làm việc theo cách khác - tìm cha mẹ với một đứa trẻ cụ thể. –

Các vấn đề liên quan