如何使用LINQ to XML来获得属性值?(How to get attribute value

2019-08-08 09:40发布

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

使用上面的代码,我可以得到下面的结果:

但我需要的列WorkPhone的价值424-555-0545 ,而不是Home和列HomePhone的价值423-555-0124 ,而不是Home

我应该为此做什么?

Answer 1:

使用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
  • Single会得到满足指定属性(如果有0或大于1个元件满足属性,则产生错误)的元素。
  • phoneElement.Attribute("Type").Value是属性“类型”(即“家”或“工作”)的值

然后,你的代码应该是:

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将等于null ,如果没有“phone”元素满足条件和string投上XElement相当于XElement.Value



Answer 2:

如果有任何这段代码甚至工作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")                               
    };

使用铸造元素stringint等,而不是访问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>


文章来源: How to get attribute value using LINQ to XML?