6
<?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データを読み込もうとしていますが、これまでのところ私はこれを試しました:

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

しかし、子ノードから値を取得してフィルタリングを適用する方法がわかりません(特定の従業員のみを取得するため)。これは可能ですか?どんな助けでも大歓迎です。

ありがとう

4

3 に答える 3

8
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();
于 2013-09-19T09:46:59.183 に答える
6

構造を追跡できます。

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<Region> 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();
       }
于 2013-09-19T09:46:47.393 に答える