LINQ to Xml: lựa chọn các yếu tố nếu giá trị thuộc tính tương đương với một giá trị nút trong một IEnumerable <XElement>


8

tôi có thể tạo một đối tượng IEnumerable mà chỉ chứa các nút Tôi muốn từ một file xml:

IEnumerable<XElement> rosters = XDocument.Load("roster.xml") 
             .Elements("rosterlist") 
             .Elements("roster") 
             .Where(w => w.Element("division") 
                 .Value 
                 .Equals("SUPER AWESOME DIVISION")); 

Vì vậy, nó là một tập hợp các sau đây:

<rosterlist> 
    <roster> 
     <userid>1</userid> 
     <name></name> 
     <etc></etc> 
    </roster> 
    <roster> 
     <userid>2</userid> 
     <name></name> 
     <etc></etc> 
    </roster> 
</rosterlist> 

tôi muốn lấy chỉ những người dùng mà các thuộc tính userid cũng là một nút userid trong bộ sưu tập rosters.

IEnumerable<XElement> users = XDocument.Load("user.xml") 
             .Elements("userlist") 
             .Elements("user") 
             .Where(w => rosters.Elements("userid") 
                  .Contains(w.Attribute("userid").Value)); 

Nhưng nó đem lại cho tôi một lỗi:

Những lập luận kiểu cho phương pháp 'System.Linq.Enumerable.Contains (System.Collections.Generic.IEnumerable, TSource)' không thể được suy ra từ sử dụng. Hãy thử xác định các đối số kiểu một cách rõ ràng.

Điều gì là sai với cách tiếp cận của tôi?

6

Một vấn đề tôi thấy là trong đoạn mã cuối cùng, ...Elements("userid") trả về danh sách các đối tượng XElement không thể chứa Chuỗi được trả về bởi thuộc tính Giá trị. Điều này sẽ làm việc ...

IEnumerable<XElement> rosters = obRoot.Elements("rosterlist").Elements("roster"); 
var rosterUserIds = (rosters.Elements("userid").Select(r => r.Value)); 
IEnumerable<XElement> users = obRoot.Elements("userlist").Elements("user") 
       .Where(u => rosterUserIds.Contains(u.Attribute("userid").Value)); 

Tuy nhiên tôi muốn làm điều này bằng cách sử dụng một truy vấn tham gia .. Chọn người dùng tham gia rosters trên userid
Nó muốn đi một cái gì đó như thế này

string sXml = @" 
<root> 
<rosterlist> 
    <roster> 
     <userid>1</userid> 
     <name>R1</name> 
     <etc></etc> 
    </roster> 
    <roster> 
     <userid>2</userid> 
     <name>R2</name> 
     <etc></etc> 
    </roster> 
</rosterlist> 
<userlist> 
    <user userid='1'> 
     <name>User on roster</name> 
    </user> 
    <user userid='5'> 
     <name>User not on roster</name> 
    </user> 
</userlist> 
</root> 

"; 

XElement obRoot = XElement.Parse(sXml); 
var results = from user in obRoot.Elements("userlist").Elements("user") 
    join roster in obRoot.Elements("rosterlist").Elements("roster") 
    on user.Attribute("userid").Value equals roster.Element("userid").Value 
    select new {Name=user.Element("name").Value, RosterName=roster.Element("name").Value} ; 

foreach (var v in results) 
{ 
    Console.WriteLine("{0, -20} on Roster {1, -20}", v.Name, v.RosterName); 
} 

Đầu ra:

User on roster  on Roster R1