簡體   English   中英

Linq to XML:使用元素屬性和值創建一個匿名對象

[英]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.Valuea.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM