如何使用不同元素的属性进行Linq XML连接

时间:2015-03-11 15:32:14

标签: c# linq attributes linq-to-xml element

好的,抱歉,但请注意我的问题非常清楚。

<DATA>
   <USERS>
      <USER USER_ID="344351">
         <NAME>John</NAME>
         <FIRST_NAME>Wick</FIRST_NAME>
      </USER>

      <USER>
      ...
      </USER>
   </USERS>

   <OFFICES>
      <OFFICES_USER USER_ID="344351">
        <OFFICE>
          <ROOM_ID>B321</ROOM_ID>
          <ROOM_TYPE>D</ROOM_TYPE>
        </OFFICE>
      </OFFICES_USER>

      <OFFICES_USER USER_ID="345251">
        <OFFICE>
          <ROOM_ID>C340</ROOM_ID>
          <ROOM_TYPE>D</ROOM_TYPE>
        </OFFICE>
      </OFFICES_USER>
   </OFFICES>

</DATA>

继承我的代码以检索一些数据:

List<C_USER> L = (from el in userxml.Descendants("USER")
                  orderby (string)el.Element("NAME")
                  select new C_USER()
                         {
                          name = (string)el.Element("NAME").Value,
                          fname = (string)el.Element("FIRST_NAME").Value,
                          office_room = ???,
                         }).ToList();

C_USER是一个包含name,fname,office_room的类。

我希望通过匹配元素USER和元素OFFICE中的属性USER_ID来获取房间ID。

我对C#和LinQ都很陌生,所以请原谅我:)

结果将是: 名字:威克 fname:约翰 office_room:B321

我尝试过后代,但我没有成功提取ROOM_ID(2个后代)

谢谢你!

2 个答案:

答案 0 :(得分:0)

你必须做这样的事情:

office_room =(from offices in userxml.Descendants("OFFICES")
              from office in offices.Descendants("OFFICE") 
              where offices.Attribute("USER_ID").Value == el.Attribute("USER_ID").Value
              select office.Element("ROOM_ID").Value).FirstOrDefault()

答案 1 :(得分:0)

如果您更喜欢方法语法,可以这样做: -

XDocument xdoc = XDocument.Load(@"YourXML.xml");
var result = xdoc.Descendants("USER")
      .Select(x => 
    {
        var first = x.Document.Root.Descendants("OFFICE")
                     .FirstOrDefault(o => (string)o.Parent.Attribute("USER_ID") == 
                                          (string)x.Attribute("USER_ID"));
        return new C_USER
         {
            name = (string)x.Element("NAME"),
            fname = (string)x.Element("FIRST_NAME"),
            office_room = first != null ? (string)first.Element("ROOM_ID") : String.Empty
         };
    });

<强>步骤:

1.获取name&amp; fname非常简单,因为我们是从USER的后代中取出它们 2. x拥有USER的后代,所以首先我们需要回到Root,我正在使用x.Document.Root并最终获取OFFICE的后代。由于我们需要匹配USER_ID我使用FirstOrDefault来过滤掉相同的内容 3.最后从步骤2中检索到的集合中获取Room_ID

请注意,如果“{1}}”与“用户”和“用户”匹配,则可能会收到object reference error在这种情况下,USER_ID以后的办事处将返回null。