[英]Linq to XML: create an anonymous object with element attributes and values
我是Linq的新手,正在嘗試查詢XML文檔以查找特定用戶的客戶經理列表。 (我意識到將其放入數據庫或其他內容可能更有意義,但是這種情況需要使用XML文檔)。
<user emailAddress='user@fabrikam.com'>
<accountManager department='Customer Service' title='Manager'>manager@fabrikam.com</accountManager>
<accountManager department='Sales' title='Account Manager'>manager@fabrikam.com</accountManager>
<accountManager department='Sales' title='Account Manager'>manager@fabrikam.com</accountManager>
</user>
我試圖創建具有XElement屬性(部門,標題)和值(電子郵件)組成的屬性的對象列表(匿名類型?)。 我知道我可以兩者兼得,但我的問題是兩者都選。
這是我正在嘗試的:
var managers = _xDoc.Root.Descendants("user")
.Where(d => d.Attribute("emailAddress").Value == "user@fabrikam.com")
.SelectMany(u => u.Descendants("accountManager").Select(a => a.Value));
foreach (var manager in managers)
{
//do stuff
}
我可以在a.Value
和a.Attribute
,但我無法弄清楚如何讓兩者並將其存儲在一個對象。 我有一種感覺,它看起來像:
select new {
department = u.Attribute("department").Value,
title = u.Attribute("title").Value,
email = u.Value
};
你是對的。 看起來就像那樣。
例如:
_xDoc.Root.Descendants("user")
.Where(d => d.Attribute("emailAddress").Value == "user@fabrikam.com")
.SelectMany(u => u.Descendants("accountManager"))
.Select(a => new {
department = a.Attribute("department").Value,
title = a.Attribute("title").Value,
email = a.Value
});
編輯 :使用查詢理解語法:
from u in _xDoc.Root.Descendants("user")
where u.Attribute("emailAddress").Value == "user@fabrikam.com"
from a in u.Descendants("accountManager")
select new {
department = a.Attribute("department").Value,
title = a.Attribute("title").Value,
email = a.Value
});
如果要從Select
方法返回匿名類型,可以編寫:
var managers =
_xDoc.Root.Descendants("user")
.Where(d => d.Attribute("emailAddress").Value == "user@fabrikam.com")
.SelectMany(u =>
u.Descendants("accountManager")
.Select(a => new {
Department = u.Attribute("department").Value,
Title = u.Attribute("title").Value,
Email = u.Value })
);
創建匿名類型的語法並不直接綁定到select
關鍵字。 您可以像這樣使用它:
var manager = new { Department = "Somewhere", Title = "Mr" };
因此,語法a => new { ... }
是返回新匿名類型的lambda表達式,就像select new { ... }
是構造新匿名類型的子句一樣。
關於在點符號和查詢語法之間進行選擇-這確實是個人喜好(盡管使用查詢語法時某些情況看起來更好,並且諸如Count
某些方法只能使用點符號來使用)。 但是,所有查詢都由編譯器轉換為方法調用。
我假設只有一個用戶sipAddress == sipUri
?
讓我們從這個開始:
var managers = _xDoc.Root
您可以使用.First
僅選擇匹配的第一個元素.First
.First(d => d.Attribute("sipAddress").Value == sipUri)
這將使第一個用戶謂詞返回true。 然后,您需要將元素中的屬性和值都提取到一個新對象(匿名類型)中。
如果有很多用戶,並且您想要列出的所有經理,則可以使用.SelectMany
(即,對於每個用戶,有很多經理,選擇所有經理)來完成此操作,但在這種情況下,我假設只有一個,並且.First
已返回該元素,因此您只需使用其屬性即可訪問經理列表
.Descendants("accountManager")
然后,您將獲得所有從選定元素降序的XElement
。 使用元素中的值將其轉換為另一個對象是通過使用映射函數完成的,在Linq中是.Select
.Select(managerElem => new {
department = u.Attribute("department").Value,
title = u.Attribute("title").Value,
email = u.Value
});
如前所述,如果有多個用戶使用正確的sipAddress
並且您希望所有管理者,只需將.Descendants
包裝在.SelectMany
。
.SelectMany(userElem => userElem.Descendants("accountManager"))
我尚未測試過代碼,但我相信您可以按照我寫的內容弄清楚。
希望這可以幫助! :)隨時在評論中詢問您是否仍然感到困惑。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.