Linq on XML从select中的嵌套元素获取价值

时间:2018-08-09 13:00:36

标签: c# xml linq

我有这个XML代码,可以使用linq在上面执行select语句。但是我在获得嵌套值角色时遇到问题。

<persons>
  <person>
    <name>
      <fn>Donald Duck</fn>
      <n>
        <family>Duck</family>
        <given>Donald</given>
      </n>
    </name>
    <email />
    <tel teltype="voice" />
    <tel teltype="mobile" />
    <adr>
    </adr>
    <institutionrole roletype="Employee" />
    <extension>
      <institutions>
        <institution institution="Division1">
          <role>sales</role>
        </institution>
        <institution institution="Division2">
          <role>observer</role>
        </institution>
      </institutions>
    </extension>
  </person>
</persons>

我选择所有人员并过滤,例如,机构=部门1 然后,我希望在该机构中发挥作用的价值。

到目前为止我的代码,但是let role =不起作用

var users = (from person in xmlDoc.Descendants("person")
let role = person.Element("extension").Descendants("institutions").SingleOrDefault(ins => ins.Elements("institution").Attribute("institution").Value.ToLower() == units).Select(ins => ins.Element("role")).FirstOrDefault().ToString()
 where person.Element("extension").Descendants("institutions").Elements("institution").Attributes("institution").Where(ins => ins.Value.ToLower() == units).Any();
select new User(){
      userRole = role,
      UserLastname = person.Element("name").Element("n").Element("family").Value,
      UserFirstname = person.Element("name").Element("n").Element("given").Value
    }).ToArray();

2 个答案:

答案 0 :(得分:0)

好的,我已经完全重写了您的查询,以便最终得到institution元素和n元素,而不是尝试直接在let子句中查找角色。我认为这最终是一个更简单的查询。我还要说的是,使用垂直空间比创建很长的线条更容易阅读-尽管那是主观的。

我使用了从XAttributeXElementstring的显式转换,而不是使用Value属性。这在缺少元素的情况下(根据您要实现的目标)“更好”(取决于结果,我们最终得到的是null值而不是异常),并且我发现它更易于阅读。再次,这有点主观。

using System;
using System.Linq;
using System.Xml.Linq;

class Test
{
    static void Main()
    {
        var doc = XDocument.Load("test.xml");
        var targetInstitution = "Division1";

        var users =
            from person in doc.Root.Elements("person")
            let name = person.Element("name").Element("n")
            let institution = person
                .Element("extension")
                .Elements("institutions")
                .Elements("institution")
                .SingleOrDefault(ins => (string) ins.Attribute("institution") == targetInstitution)
            // Only include users where we've foudn the institution
            where institution != null
            select new
            {
                UserRole = (string) institution.Element("role"),
                UserFirstName = (string) name.Element("given"),
                UserLastName = (string) name.Element("family")
            };

        foreach (var user in users)
        {
            Console.WriteLine(user);
        }
    }
}

输出您的测试文件:

{ UserRole = sales, UserFirstName = Donald, UserLastName = Duck }

答案 1 :(得分:0)

以下代码将返回属性institution等于institution的{​​{1}}元素中的所有角色

division1

希望这对您有所帮助。