使用LINQ解析XML以获取子元素

           public class Employee { public string EmployeeName { get; set; } public string DeptId { get; set; } public List RegionList {get; set;} } public class Region { public string RegionName { get; set; } public string AreaCode { get; set; } } 

我试图读取这个XML数据,到目前为止我已经尝试过:

 XDocument xml = XDocument.Load(@"C:\data.xml"); var xElement = xml.Element("CompanyInfo"); if (xElement != null) foreach (var child in xElement.Elements()) { Console.WriteLine(child.Name); foreach (var item in child.Attributes()) { Console.WriteLine(item.Name + ": " + item.Value); } foreach (var childElement in child.Elements()) { Console.WriteLine("--->" + childElement.Name); foreach (var ds in childElement.Attributes()) { Console.WriteLine(ds.Name + ": " + ds.Value); } foreach (var element in childElement.Elements()) { Console.WriteLine("------->" + element.Name); foreach (var ds in element.Attributes()) { Console.WriteLine(ds.Name + ": " + ds.Value); } } } } 

这使我能够获取每个节点,其属性名称和值,因此我可以将这些数据保存到数据库中的相关字段中,但这似乎是一种漫长的方式并且不灵活,例如,如果XML结构更改了所有这些foreach语句需求重新访问,也很难以这种方式过滤数据,我需要写一些if语句来过滤数据(例如从West获取员工等…)

我正在寻找一种更灵活的方式,使用linq,如下所示:

 List employees = (from employee in xml.Descendants("CompanyInfo") select new employee { EmployeeName = employee.Element("employee").Value, EmployeeDeptId = ?? get data, RegionName = ?? get data, AreaCode = ?? get data,, }).ToList(); 

但我不知道如何从子节点获取值并应用过滤(仅限某些员工)。 这可能吗? 任何帮助表示赞赏。

谢谢

 var employees = (from e in xml.Root.Elements("Employee") let r = e.Element("Region") where (string)r.Attribute("name") == "West" select new Employee { EmployeeName = (string)e.Attribute("employee"), EmployeeDeptId = (string)e.Attribute("deptId"), RegionName = (string)r.Attribute("name"), AreaCode = (string)r.Element("Area").Attribute("code"), }).ToList(); 

但是当XML文件结构发生变化时,它仍然需要进行查询修订。

编辑

查询每位员工的多个区域:

 var employees = (from e in xml.Root.Elements("Employee") select new Employee { EmployeeName = (string)e.Attribute("employee"), DeptId = (string)e.Attribute("deptId"), RegionList = e.Elements("Region") .Select(r => new Region { RegionName = (string)r.Attribute("name"), AreaCode = (string)r.Element("Area").Attribute("code") }).ToList() }).ToList(); 

然后,您可以仅过滤来自给定区域的员工的列表:

 var westEmployees = employees.Where(x => x.RegionList.Any(r => r.RegionName == "West")).ToList(); 

您可以跟踪结构:

 from employee in xml .Element("CompanyInfo") // must be root .Elements("Employee") // only directly children of CompanyInfo 

或者不太严格

 from employee in xml.Descendants("Employee") // all employees at any level 

然后获取您想要的信息:

  select new Employee { EmployeeName = employee.Attribute("name").Value, EmployeeDeptId = employee.Attribute("deptId").Value, RegionName = employee.Element("Region").Attribute("name").Value, AreaCode = employee.Element("Region").Element("Area").Attribute("code").Value, } 

有了多个区域的附加信息,假设List Regions属性:

  select new Employee { EmployeeName = employee.Attribute("name").Value, EmployeeDeptId = employee.Attribute("deptId").Value, //RegionName = employee.Element("Region").Attribute("name").Value, //AreaCode = employee.Element("Region").Element("Area").Attribute("code").Value, Regions = (from r in employee.Elements("Region") select new Region { Name = r.Attribute("name").Value, Code = r.Element("Area").Attribute("code").Value, }).ToList(); } 

您可以在一个查询中进行选择,然后在第二个中进行过滤,或者将它们组合到一个查询中:

两个问题:

  // do te transformation var employees = from employee in xml.Descendants("CompanyInfo").Elements("Employee") select new { EmployeeName = employee.Attribute("name").Value, EmployeeDeptId = employee.Attribute("deptId").Value, Regions = from region in employee.Elements("Region") select new { Name = region.Attribute("name").Value, AreaCode = region.Element("Area").Attribute("code").Value, } }; // now do the filtering var filteredEmployees = from employee in employees from region in employee.Regions where region.AreaCode == "96" select employee; 

组合一个查询(相同的输出):

  var employees2 = from selectedEmployee2 in from employee in xml.Descendants("CompanyInfo").Elements("Employee") select new { EmployeeName = employee.Attribute("name").Value, EmployeeDeptId = employee.Attribute("deptId").Value, Regions = from region in employee.Elements("Region") select new { Name = region.Attribute("name").Value, AreaCode = region.Element("Area").Attribute("code").Value, } } from region in selectedEmployee2.Regions where region.AreaCode == "96" select selectedEmployee2; 

但是你应该考虑添加一件小事。 为了增强稳定性,您需要检查元素和属性的存在,然后选择将如下所示:

  var employees = from employee in xml.Descendants("CompanyInfo").Elements("Employee") select new { EmployeeName = (employee.Attribute("name") != null) ? employee.Attribute("name").Value : string.Empty, EmployeeDeptId = (employee.Attribute("deptId") != null) ? employee.Attribute("deptId").Value : string.Empty, Regions = (employee.Elements("Region") != null)? from region in employee.Elements("Region") select new { Name = (region.Attribute("name")!= null) ? region.Attribute("name").Value : string.Empty, AreaCode = (region.Element("Area") != null && region.Element("Area").Attribute("code") != null) ? region.Element("Area").Attribute("code").Value : string.Empty, } : null };