C# Linq to Xml:如果属性值等于 IEnumerable<XElement> 中的节点值,则选择元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/574432/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 08:50:04  来源:igfitidea点击:

Linq to Xml: selecting elements if an attribute value equals a node value in an IEnumerable<XElement>

c#asp.netxmllinq

提问by lolcat

I create an IEnumerable object that just contains the nodes I want from an xml file:

我创建了一个 IEnumerable 对象,它只包含我想要的 xml 文件中的节点:

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

So it's a collection of these:

所以它是这些的集合:

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

I want to grab only the users where the useridattribute is also a useridnode within the rosterscollection.

我只想获取userid属性也是集合中userid节点的用户rosters

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

But it is giving me an error:

但它给了我一个错误:

The type arguments for method 'System.Linq.Enumerable.Contains(System.Collections.Generic.IEnumerable, TSource)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

无法从用法推断方法“System.Linq.Enumerable.Contains(System.Collections.Generic.IEnumerable, TSource)”的类型参数。尝试明确指定类型参数。

What is wrong with my approach?

我的方法有什么问题?

采纳答案by Gishu

One issue I see is that in the last code snippet, ...Elements("userid")returns a list of XElement objects which cannot contain a String returned by the Value property. This should work...

我看到的一个问题是,在最后一个代码片段中,...Elements("userid")返回一个 XElement 对象列表,其中不能包含 Value 属性返回的字符串。这应该工作...

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));

However I'd do this by using a join query.. Select user join rosters on userid
It'd go something like this

但是我会通过使用连接查询来做到这一点.. 在 userid 上选择用户加入名册
它会是这样的

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);
}

Outputs:

输出:

User on roster       on Roster R1