LINQ To XML : Descendants函式

iSQlServer發表於2010-03-21

LINQ To XML : Descendants函式
 

    在LINQ To XML 的架構中,若想取得某個Element下的指定之子Element,可以呼叫Descendants這個Extension Method,如下所示:
foreach (XElement elem in doc.Elements("Customers").Descendants("Customer"))
      Console.WriteLine(string.Format("Customer ID : {0}, Name : {1}, Address : {2}",
                                                elem.Attribute("ID").Value,
                                                elem.Attribute("Name").Value,
                                                elem.Attribute("Address").Value));

此例所使用的XML如下:


 
 
 

不過,這有個特別的情況,當XML中包含了Namespace時,傳入Descendants的指定Element名稱就必須包含Namespace,舉個例來說,下面的.dbml(LINQ To SQL的定義檔)。

        xmlns="http://schemas.microsoft.com/linqtosql/dbml/2007">
 "Data Source=JEFFRAY;Initial Catalog=Northwind;Integrated Security=True"SettingsObjectName="LTSync.Properties.Settings"SettingsPropertyName="NorthwindConnectionString"Provider="System.Data.SqlClient" />
...........
 

如果用下面的程式來列舉Connection Element,會以失敗收場。
var cstr = (from s1 in doc.Descendants("Connection") select s1).First();

問題的徵結點在於.dbml中定義了Namespace,而我們於呼叫Descendants時,只傳入Element的LocalName部份所致,仔細檢視Descendants函式的宣告,你會發現其事實上接收的是一個XName型別的物件,由於XName實作了隱含轉型運運算元,所以很自然的將我們傳入的字串隱含轉型為XName,只是此
時得到的XName物件中只包含了LocalName部份,並未包含Namespace部份。
要順利取得Connection Element,我們可以用下面的程式碼來達成。
var cstr = (from s1 in doc.Descendants() where s1.Name.LocalName == "Connection"select s1).First(); 

此例中我們以未帶引數的Descendants函式來取得所有子Element,並一一比對其LocalName,忽略掉Namespace。
另一個手法是直接以Root Element的Namespace來疊加LocalName,如下所示:
var cstr = (from s1 in doc.Descendants(doc.Root.Name.Namespace+"Connection") select s1).First(); 

此手法的缺點是,欲取得的Element之Namespace必須與Root Element相同。

詳細出處參考:http://www.itqun.net/content-detail/140097_2.html

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16436858/viewspace-630025/,如需轉載,請註明出處,否則將追究法律責任。

相關文章