如何使用LINQ to XML获取属性值?

15
<Employees>
  <Employee>
    <EmpId>1</EmpId>
    <Name>Sam</Name>
    <Sex>Male</Sex>
    <Phone Type="Home">423-555-0124</Phone>
    <Phone Type="Work">424-555-0545</Phone>
  </Employee>
</Employees>

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    emplyeeDetails = XDocument.Load(Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName + "\\LinqToXml\\Xmls\\" + "Employees.xml");
    var emplyees = from emp in emplyeeDetails.Descendants("Employee").Take(10)
                   orderby emp.Element("EmpId").Value ascending
                   select new
                   {
                       Id = emp.Element("EmpId").Value,
                       Name = emp.Element("Name").Value,
                       Sex = emp.Element("Sex").Value,
                       WorkPhone=emp.Element("Phone").Attribute("Type").Value,
                       HomePhone = emp.Element("Phone").Attribute("Type").Value,                               
                   };
    DgrdEmployeeDetails.ItemsSource = emplyees.ToList();
}
使用上述代码,我可以得到以下结果: enter image description here 但是我需要列WorkPhone的值为424-555-0545而不是Home,以及列HomePhone的值为423-555-0124而不是Home
我该怎么做呢?
2个回答

15

使用Where方法:

对于家庭电话号码

emp.Elements("Phone").Single(phoneElement => phoneElement.Attribute("Type").Value == "Home").Value

关于工作电话

emp.Elements("Phone").Single(phoneElement => phoneElement.Attribute("Type").Value == "Work").Value
  • emp.Elements("Phone") 是对 emp 中所有 "Phone" 元素的可枚举对象。
  • Single 将获取满足指定属性的元素(如果有0个或多个满足该属性的元素,则会引发错误)。
  • phoneElement.Attribute("Type").Value 是属性 "Type" 的值(即 "Home" 或 "Work")。

然后,您的代码应该如下:

var emplyees = from emp in emplyeeDetails.Descendants("Employee").Take(10)
                orderby emp.Element("EmpId").Value ascending
                select new
                {
                    Id = emp.Element("EmpId").Value,
                    Name = emp.Element("Name").Value,
                    Sex = emp.Element("Sex").Value,
                    WorkPhone = emp.Elements("Phone").Single(phoneElement => phoneElement.Attribute("Type").Value == "Home").Value,
                    HomePhone = emp.Elements("Phone").Single(phoneElement => phoneElement.Attribute("Type").Value == "Work").Value,
                };

如果元素 emp 可能没有 工作 电话或 家庭 电话号码,那么上述代码会在 Single 中引发异常。要处理这种情况,您需要更改您的代码为:

(string)emp.Elements("Phone").SingleOrDefault(phoneElement => phoneElement.Attribute("Type").Value == "Home")

SingleOrDefault如果没有任何“Phone”元素满足条件,则将等于null,对XElement执行的string转换相当于XElement.Value


在C# 6+中,你可以使用Null-conditional operator代替强制类型转换来避免NullReferenceException。因此代码看起来像这样:Name = emp.Element("Name")?.Value; - Lauren Rutledge

3
这段代码可以正常运行,即使员工中有任何 Phone 元素存在:
var emplyees = 
    from emp in emplyeeDetails.Descendants("Employee").Take(10)
    let phones = emp.Descendants("Phone")
    orderby (int)emp.Element("EmpId")
    select new
    {
        Id = (int)emp.Element("EmpId"),
        Name = (string)emp.Element("Name"),
        Sex = (string)emp.Element("Sex"),
        WorkPhone = (string)phones.FirstOrDefault(p => (string)p.Attribute("Type") == "Work"),
        HomePhone = (string)phones.FirstOrDefault(p => (string)p.Attribute("Type") == "Home")                               
    };

使用类型转换元素来将元素转换为字符串、整数等,而不是访问Value属性。为什么?因为如果您的xml中缺少某些元素或属性,那么您将会得到一个NullReferenceException异常。但是,类型转换将返回默认值。因此,即使是像这样的xml,上面的代码也能解析:

<Employees>
  <Employee>
    <EmpId>1</EmpId>
    <Name>Sam</Name>
    <Phone Type="Home">423-555-0124</Phone>
    <Phone>524-777-1234</Phone>
  </Employee>
</Employees>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接