使用LINQ解析XML以获取子元素 [英] Parse XML with LINQ to get child elements

查看:92
本文介绍了使用LINQ解析XML以获取子元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

<?xml version="1.0" standalone="yes"?>
<CompanyInfo>
     <Employee name="Jon" deptId="123">
      <Region name="West">
        <Area code="96" />
      </Region>
      <Region name="East">
        <Area code="88" />
      </Region>
     </Employee>
</CompanyInfo>  

public class Employee
{
    public string EmployeeName { get; set; }
    public string DeptId { get; set; }
    public List<string> RegionList {get; set;}
}

public class Region
{
    public string RegionName { get; set; }
    public string AreaCode { get; set; }
}

我正在尝试读取此XML数据,到目前为止,我已经尝试过:

I am trying to read this XML data, so far I have tried this:

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获得雇员等)

This enables me to get each node, its attribute name and value and so I can save these data into the relevant field in database, but this seems a long winded way and not flexible, for instance if the XML structure changes all those foreach statements needs revisiting, also it is difficult to filter the data this way, I need to write certain if statements to filter the data (e.g get employees from West only etc...)

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

I was looking for a more flexible way, using linq, something like this:

List<Employees> 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<Employee>();

但是我不确定如何从子节点中获取值并应用过滤(仅获取某些员工).这可能吗?感谢您的帮助.

But I am not sure how I can get the values from the child nodes and apply the filtering (to get the certain employees only). Is this possible? Any help is appreciated.

谢谢

推荐答案

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文件结构更改时,仍然需要查询修订.

But it will still require query revision when XML file structure changes.

编辑

Edit

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

Query for multiple regions per employee:

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

然后,您可以仅过滤给定区域中的雇员的列表:

You can then filter the list for employees from given region only:

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

这篇关于使用LINQ解析XML以获取子元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆