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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14539897/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 12:12:47  来源:igfitidea点击:

How to get attribute value using LINQ to XML?

c#xmllinqlinq-to-xml

提问by Chandru A

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

Using the code above, I can get the result below: enter image description here

使用上面的代码,我可以得到以下结果: 在此处输入图片说明

But I need the column WorkPhone's value 424-555-0545instead of Homeand the column HomePhone's value 423-555-0124instead of Home.

但我需要列WorkPhone的值424-555-0545而不是HomeHomePhone的值423-555-0124而不是Home.

What should I do for that?

我该怎么做?

采纳答案by Cédric Bignon

Use the Wheremethod:

使用Where方法:

For the Homephone number:

对于家庭电话号码:

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

For the Workphone number:

对于工作电话号码:

emp.Elements("Phone").Single(phoneElement => phoneElement.Attribute("Type").Value == "Work").Value
  • emp.Elements("Phone")is a enumerable on all "Phone" elements of emp.
  • Singlewill get the element that satisfy the specified property (if there are 0 or more than 1 element that satisfy the property, an error is raised).
  • phoneElement.Attribute("Type").Valueis the value of the attribute "Type" (ie "Home" or "Work")
  • emp.Elements("Phone")是 的所有“电话”元素的可枚举项emp
  • Single将获取满足指定属性的元素(如果有 0 个或超过 1 个元素满足该属性,则会引发错误)。
  • phoneElement.Attribute("Type").Value是属性“类型”(即“家庭”或“工作”)的值

Then, your code should be:

然后,您的代码应该是:

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

If the element empmay have no Workphone or Homephone number, the above code will raise an exception in the Single. To deal with this case you have to change your code to:

如果元素emp可能没有工作电话或家庭电话号码,则上述代码将在Single. 要处理这种情况,您必须将代码更改为:

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

SingleOrDefaultwill equal nullif no "Phone" element satisfy the condition and the stringcast on a XElementis equivalent to XElement.Value.

SingleOrDefault将等于null如果没有“电话”元素满足条件和string上铸造XElement相当于XElement.Value

回答by Sergey Berezovskiy

This code will work even if there is any Phoneelements exist for employee:

即使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")                               
    };

Use casting elements to string, int, etc instead of accessing Valueproperty. Why? Because if there is some missing element or attribute in your xml, then you will get a NullReferenceException. But casting will return default value instead. So, code above will parse even xml like this:

使用将元素转换为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>