2010-02-24 75 views
5

XML樣本(original link):如何獲得所有的「屬性」,從XML通過LINQ爲xml

<records> 
    <record index="1"> 
    <property name="Username">Sven</property> 
    <property name="Domain">infinity2</property> 
    <property name="LastLogon">12/15/2009</property> 
    </record> 
    <record index="2"> 
    <property name="Username">Josephine</property> 
    <property name="Domain">infinity3</property> 
    <property name="LastLogon">01/02/2010</property> 
    </record> 
    <record index="3"> 
    <property name="Username">Frankie</property> 
    <property name="Domain">wk-infinity9</property> 
    <property name="LastLogon">10/02/2009</property> 
    </record> 
</records> 

我想在XML中每一個記錄類的一個實例。

我在這裏發現了類似的例子,但他們只有一個根,然後一個元素深。它的工作原理,正確的,直到我把其他元素我希望能夠像做

foreach(Record rec in myVar) 
{ 
Console.WriteLine("ID: {0} User:{1} Domain:{2} LastLogon:{3}",rec.Index, rec.Username, rec.Domain, rec.LastLogon); 
} 

回答

3

編輯:更新的代碼與ToDictionary方法的效率和透明性。

您可以嘗試下面的示例。如果您從select new Record行中刪除Record,它將導致匿名類型並仍然有效。你的Record類應該有一個默認的無參數構造函數來使用對象初始值設定項,如果你已經提供了其他構造函數的話(如果你沒有構造函數,它也會工作)。否則,您可以使用可用的構造函數而不是對象初始值設定項。

請注意,Single()Value的使用假定XML格式良好,沒有任何缺失的元素。

var xml = XElement.Parse(@"<records> 
<record index=""1""> 
    <property name=""Username"">Sven</property> 
    <property name=""Domain"">infinity2</property> 
    <property name=""LastLogon"">12/15/2009</property> 
</record> 
<record index=""2""> 
    <property name=""Username"">Josephine</property> 
    <property name=""Domain"">infinity3</property> 
    <property name=""LastLogon"">01/02/2010</property> 
</record> 
<record index=""3""> 
    <property name=""Username"">Frankie</property> 
    <property name=""Domain"">wk-infinity9</property> 
    <property name=""LastLogon"">10/02/2009</property> 
</record> 
</records>"); 

var query = from record in xml.Elements("record") 
     let properties = record.Elements("property") 
           .ToDictionary(p => p.Attribute("name").Value, p => p.Value) 
     select new Record 
     { 
      Index = record.Attribute("index").Value, 
      Username = properties["Username"], 
      Domain = properties["Domain"], 
      LastLogon = properties["LastLogon"] 
     }; 

foreach(var rec in query) 
{ 
    Console.WriteLine("ID: {0} User:{1} Domain:{2} LastLogon:{3}", rec.Index, rec.Username, rec.Domain, rec.LastLogon); 
} 

編輯:我已經更新了代碼樣品上方與ToDictionary方法,其是清潔器和更快。根據我的標杆努力,最快的是ToDictionary,其次是Func,然後是Where的做法。

原始查詢

var query = from record in xml.Elements("record") 
      let properties = record.Elements("property") 
      select new Record 
      { 
       Index = record.Attribute("index").Value, 
       Username = properties.Where(p => p.Attribute("name").Value == "Username").Single().Value, 
       Domain = properties.Where(p => p.Attribute("name").Value == "Domain").Single().Value, 
       LastLogon = properties.Where(p => p.Attribute("name").Value == "LastLogon").Single().Value 
      }; 

查詢與Func鍵

可以通過下面的代碼可以減少

原始查詢的冗餘:

Func<XElement, string, string> GetAttribute = 
      (e, property) => e.Elements("property") 
          .Where(p => p.Attribute("name").Value == property) 
          .Single().Value; 

var query = from record in xml.Elements("record") 
      select new Record 
      { 
       Index = record.Attribute("index").Value, 
       Username = GetAttribute(record, "Username"), 
       Domain = GetAttribute(record, "Domain"), 
       LastLogon = GetAttribute(record, "LastLogon") 
      }; 
+0

PERFICT!我一直試圖找出現在2-3天。我的前途是疼痛和紅色。你推薦哪些書來調節LINQ(和C#)。 – 2010-02-24 05:43:33

+0

@Sunzaru我喜歡LINQ in Action(http://www.amazon.com/dp/1933988169/),或者您可能希望獲得一本C#4.0/.NET 4.0書籍來涵蓋一些新的材料。簡單的C#4.0是很好的,但它涵蓋了大量的材料。我還推薦下載LINQPad(http://www.linqpad.net/)並瀏覽它附帶的Nutshell樣本(由本書作者製作)。您也可以通過它下載LINQ in Action示例。也許在購買書籍之前先做到這一點:) – 2010-02-24 05:52:37

+0

我今天測試過,平均處理時間爲120MS。但在那些120MS中,我還在尋找其他一些沒有提到的指標。快速..光滑和zomg .. sooo比「編輯 - >查找」更好。再次感謝! – 2010-02-25 01:04:49

相關問題