<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
。
我应该为此做什么?
使用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
。
如果有任何这段代码甚至工作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")
};
使用铸造元素string
, int
等,而不是访问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>