2012-02-07 76 views
13

我有一個包含了一系列的項目節點,看起來像這樣的XML文檔:用LINQ查詢XDocument的最佳方法是什麼?

<data> 
    <item> 
     <label>XYZ</label> 
     <description>lorem ipsum</description> 
     <parameter type="id">123</parameter> 
     <parameter type="name">Adam Savage</parameter> 
     <parameter type="zip">90210</parameter> 
    </item> 
</data> 

,我想它的LINQ到一個匿名類型是這樣的:

var mydata = 
    (from root in document.Root.Elements("item") 
    select new { 
     label = (string)root.Element("label"), 
     description = (string)root.Element("description"), 
     id = ..., 
     name = ..., 
     zip = ... 
    }); 

什麼是最好的方式根據其'type'屬性的值拉取每個參數類型?由於有很多參數元素,您可以使用root.Elements("parameter")這是一個集合。我能想到的最好的方法就是像下面這樣的方法,但我覺得必須有更好的方法?

(from c in root.Descendants("parameter") where (string)c.Attribute("type") == "id" 
select c.Value).SingleOrDefault() 

回答

25

我會使用內置的查詢方法在LINQ to XML,而不是(除xmlreader但如果是一個很多) XPath的。您的查詢看起來不錯,除了:

  • 如果有多個項目,你需要找到它的後代,或者只是使用Element如果你正在尋找項目的直接後裔
  • 你可能想一次拉所有值,並將其轉換成一個字典
  • 如果您正在使用不同的數據類型的內容,您可能需要投射元素而不是使用.Value
  • 您可能希望創建一種方法,以針對給定類型返回匹配XElement,而不是有多個查詢。

就我個人而言,我不認爲我甚至會爲此使用查詢表達式。例如:

static XElement FindParameter(XElement element, string type) 
{ 
    return element.Elements("parameter") 
        .SingleOrDefault(p => (string) p.Attribute("type") == type); 
} 

然後:

var mydata = from item in document.Root.Elements("item") 
      select new { 
       Label = (string) item.Element("label"), 
       Description = (string) item.Element("description"), 
       Id = (int) FindParameter(item, "id"), 
       Name = (string) FindParameter(item, "name"), 
       Zip = (string) FindParameter(item, "zip") 
      }; 

我懷疑你會發現,這比使用XPath任何替代整潔,假設我明白你想要做什麼。

+0

是的,這似乎是一個很好的方法喬恩......我必須解決的另一個問題是,有時值是空字符串,所以有一個幫助器方法來處理屬性查詢和優雅地處理轉換爲正確的類型在空弦的事件可能是最有意義的,謝謝 – snappymcsnap 2012-02-07 23:51:27

7

使用XPATH - 這是非常快的 -

using (var stream = new StringReader(xml)) 
    { 
    XDocument xmlFile = XDocument.Load(stream); 

    var query = (IEnumerable)xmlFile.XPathEvaluate("/data/item/parameter[@type='id']"); 

    foreach (var x in query.Cast<XElement>()) 
    { 
     Console.WriteLine( x.Value); 
    } 

    } 
+7

xpath比使用內置的LINQ方法更快嗎? – snappymcsnap 2012-02-07 23:51:58

+1

一個從未回答過的不幸的問題! – 2016-04-12 22:42:48

相關問題