如何将具有复杂对象属性的对象集合绑定?

时间:2011-11-07 03:37:43

标签: c# xml linq linq-to-xml

我正在尝试加载由一组Employee对象组成的XML数据。以下函数适用于简单数据类型(如String和Int)的属性。我想知道如何导入复杂类型的数据类型。例如,

此功能正常工作:

private void LoadData()
{
   XDocument employeesDoc = XDocument.Load("Employees.xml");
   List<Employee> data = (from employee in employeesDoc.Descendants("Employee")
      select new Employee
      {
         FirstName= employee.Attribute("FirstName").Value,
         LastName = employee.Attribute("LastName ").Value,
         PhoneNumber = employee.Attribute("PhoneNumber").Value
      }).ToList();
  Employees.ItemsSource = data;
}

这是Employee类:

public class Employee
{
  public int Id { get; set; }
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public string PhoneNumber { get; set; }
  public Department Department { get; set; }
}

这是Department类:

public class Department
{
  public int Id { get; set; }
  public string Name { get; set; }
  public string Description { get; set; }
  public Employee Manager { get; set; }
}

因此,如果我的XML文件如此:

<Employees>
    <Employee FirstName="John" LastName="Summers" PhoneNumber="703-548-7841" Department="Finance"></Employee>
    <Employee FirstName="Susan" LastName="Hughey" PhoneNumber="549-461-7962" Department="HR"></Employee>

因此,如果Department是一个复杂的对象并且它是XML文件中的字符串,那么如何更改我的LoadData()函数以将其导入我的Employee对象集合?

3 个答案:

答案 0 :(得分:0)

您有几个选择,但一切都取决于您获取XML的方式(如何保存)。 (我认为)最简单的方法是:

XmlSerializer serializer = new XmlSerializer(typeof(YourType));
using (TextReader tr = new StreamReader("newSecret.xml"))
{
 YourType rrr = (YourType)serializer.Deserialize(tr);
}

此处有更多示例: http://msdn.microsoft.com/en-us/library/he66c7f1.aspx

另一方面,如果您(对某些人来说)应该使用LINQ - 请看一下: LINQ to XML: creating complex anonymous type 和这里 http://blogs.msdn.com/b/xmlteam/archive/2007/03/24/streaming-with-linq-to-xml-part-2.aspx 希望它有所帮助!

答案 1 :(得分:0)

如果您在加载员工之前可以获得所有部门的列表,则可以将部门放入Dictionary,其中密钥是部门的名称。然后,您可以为每个员工加载正确的部门:

var departmentsDict = departments.ToDictionary(d => d.Name);

XDocument employeesDoc = XDocument.Load("Employees.xml");
List<Employee> data = (from employee in employeesDoc.Descendants("Employee")
   select new Employee
   {
      FirstName= employee.Attribute("FirstName").Value,
      LastName = employee.Attribute("LastName ").Value,
      PhoneNumber = employee.Attribute("PhoneNumber").Value,
      Department = departmentsDict[employee.Attribute("Department").Value]
   }).ToList();
Employees.ItemsSource = data;

代码可能需要修改,具体取决于如果部门不存在或者某人没有指定任何部门您要执行的操作。在这两种情况下,此代码都会抛出异常。

答案 2 :(得分:0)

    using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace ConsoleApplication2
{

    public class Employee
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string PhoneNumber { get; set; }
        public Department Department { get; set; }
    }
    public class Department
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public Employee Manager { get; set; }
    }


    internal class Program
    {
        private static void Main(string[] args)
        {
            String filepath = @"C:\\rrrr.xml";

            #region Create Test Data
            List<Employee> list = new List<Employee>();
            for (int i = 0; i < 5; i++)
            {
                list.Add(new Employee
                             {
                                 Department = new Department
                                                  {
                                                      Description = "bla bla description " + i,
                                                      Id = i,
                                                      Manager = null,
                                                      Name = "bla bla name " + i
                                                  },
                                 FirstName = "First name " + i,
                                 Id = i + i,
                                 LastName = "Last name " + i,
                                 PhoneNumber = Guid.NewGuid().ToString()
                             });
            } 
            #endregion

            #region Save XML
            XmlSerializer serializer = new XmlSerializer(typeof(List<Employee>));
            using (Stream fs = new FileStream(filepath, FileMode.Create))
            {
                using (XmlWriter writer = new XmlTextWriter(fs, Encoding.Unicode))
                {
                    serializer.Serialize(writer, list);
                }
            } 
            #endregion


            //Read from XML

            XmlDocument doc = new XmlDocument();
            doc.Load(filepath);

            List<Employee> newList = new List<Employee>();
            foreach (XmlNode node in doc.GetElementsByTagName("Employee"))
            {
                Employee ee = GetEmploee(node);
                newList.Add(ee);
            }

            //ta da
        }

        public static Employee GetEmploee(XmlNode node)
        {
            return node == null
                       ? new Employee()
                       : new Employee
                             {
                                 Department = GetDepartment(node["Department"]),
                                 FirstName = (node["FirstName"]).InnerText,
                                 LastName = (node["LastName"]).InnerText,
                                 Id = Convert.ToInt32((node["Id"]).InnerText),
                                 PhoneNumber = (node["PhoneNumber"]).InnerText
                             };
        }

        public static Department GetDepartment(XmlNode node)
        {
            return node == null
                       ? new Department()
                       : new Department
                             {
                                 Description = node["Description"].InnerText,
                                 Id = Convert.ToInt32(node["Id"].InnerText),
                                 Manager = GetEmploee(node["Manager"]),
                                 Name = node["Name"].InnerText
                             };
        }
    }
}
相关问题