2013-06-03 48 views
12

我是XML和C#的新手,我試圖找到一種方法來有效地解析給定的xml文件來檢索相關的數值,基於「proj_title」value = heat_run或任何其他可能的值。例如,計算特定測試運行的持續時間(proj_end val-proj_start val)。使用C#解析XML文件?

ex.xml: 

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

... 因爲這個值是不是從試運行到固定的試運行,我們不能凸出ID搜索。上面的文件很大:〜8mb,並且有〜2000個標籤,名稱爲proj_title。有沒有一種有效的方法來首先找到所有標籤名稱w/proj_title =「heat_run」,然後檢索proj開始和結束值爲這個特定的proj_title使用C#?

這裏是我當前的C#代碼:

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

我有很多運氣使用XML序列化,你可以把你的XML轉換的對象... [這些鏈接](http://support.microsoft.com/kb/815813)可能會幫助你 –

回答

3

使用的XDocument和使用LINQ API。 http://msdn.microsoft.com/en-us/library/bb387098.aspx

如果性能不符合您的預期,您必須查找sax解析器。 Sax解析器不會將整個文檔加載到內存中,並嘗試將xpath表達式應用於內存中的所有內容。它在事件驅動方法中的作用更大,並且在某些情況下,這可以快得多並且不會使用太多的內存。

可能有SAX解析器爲.NET在附近,沒有用他們自己的.NET,但我做了C++。

14

根據現代標準,8MB真的不是很大。個人而言,我會使用LINQ到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); 
} 

(顯然調整這對自己的要求 - 這不是真的清楚你需要根據問題做什麼。)

替代查詢:

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

這幫了我很多!我只需要添加1個以上的條件。例如,LINQ/C#中是否有一個選項指向x的祖先?像Where(x =>(string)x ==「heat_run」&&(string)x.Ancestor ==「heat_test」)。我試過這個,它不起作用? – jerryh91

+0

@ jerryh91:那麼你可以使用'Parent',但我通常會反過來 - 找到一個特定的孩子的父母。 –