【问题标题】:Linq to Xml: selecting elements if an attribute value equals a node value in an IEnumerable<XElement>Linq to Xml:如果属性值等于 IEnumerable<XElement> 中的节点值,则选择元素
【发布时间】:2010-10-09 03:13:31
【问题描述】:

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

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

所以它是这些的集合:

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

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

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

但它给了我一个错误:

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

我的方法有什么问题?

【问题讨论】:

    标签: c# asp.net xml linq


    【解决方案1】:

    我看到的一个问题是,在最后一个代码 sn-p 中,...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));
    

    但是我会通过使用加入查询来做到这一点。在用户 ID 上选择用户加入名册
    会是这样的

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

    输出:

    User on roster       on Roster R1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多