Как я могу связать свою коллекцию объектов со сложным атрибутом объекта? - PullRequest
0 голосов
/ 07 ноября 2011

Я пытаюсь загрузить данные XML, которые состоят из коллекции объектов Employee.Следующая функция прекрасно работает для свойств, которые являются простыми типами данных, такими как 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; }
}

Вот класс отдела:

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>

Итак, если Департамент является сложным объектом и представляет собой строку в XML-файле, как я могу изменить свою функцию LoadData () наимпортировать его в мою коллекцию объектов Employee?

Ответы [ 3 ]

0 голосов
/ 07 ноября 2011

Если вы можете получить список всех отделов перед загрузкой сотрудников, вы можете поместить отделы в 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;

Код может нуждаться в модификации, в зависимости от того, что вы хотите сделать, если отдел не существует или если кто-то не указал какой-либо отдел,Этот код выдает исключение в обоих случаях.

0 голосов
/ 07 ноября 2011
    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
                             };
        }
    }
}
0 голосов
/ 07 ноября 2011

У вас есть несколько вариантов, но все зависит от того, как вы получили ваш 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: создание сложного анонимного типа и здесь http://blogs.msdn.com/b/xmlteam/archive/2007/03/24/streaming-with-linq-to-xml-part-2.aspx Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...