如何从这个xml反序列化集合?

时间:2015-06-15 17:00:05

标签: c# xml serialization xml-serialization deserialization

****我在xml文件中序列化我的Employee集合。当我尝试从那个或另一个反序列化集合时,程序抛出异常: 类型为" System.InvalidOperationException"的未处理异常在System.Xml.dll中 有关更多信息:文档XML(2,2)存在错误。 XML文件:

`

<?xml version="1.0" encoding="utf-8"?>
<Employees xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Items>
    <Employee>
      <FirstNameP>Ogirenko</FirstNameP>
      <AgeP>19</AgeP>
      <DepartmentP>.NET Sharepoint</DepartmentP>
      <AddressP>Kharkov</AddressP>
    </Employee>
    <Employee>
      <FirstNameP>Belous</FirstNameP>
      <AgeP>19</AgeP>
      <DepartmentP>.NET Sharepoint</DepartmentP>
      <AddressP>Kharkov</AddressP>
    </Employee>
  </Items>
</Employees>`

代码:

    public class Employee
        {
            private string FirstName;
            private string LastName;
            private int Age;
            private string Department;
            private string Address;
            private string EmpoyeeID;

            #region Properties
            public string FirstNameP
            {
                get { return FirstName; }
                set { FirstName = value; }
            }
            public string LastNameP
            {
                get { return LastName; }
                set { FirstName = value; }
            }
            public int AgeP
            {
                get { return Age; }
                set { Age = value; }
            }
            public string DepartmentP
            {
                get { return Department; }
                set { Department = value; }
            }
            public string AddressP
            {
                get { return Address; }
                set { Address = value; }
            }
            #endregion


        }
        [XmlRoot("Employees")]
        public class MyWrapper
        {
            private List<Employee> items = new List<Employee>();
            [XmlElement("Employee")]
            public List<Employee> Items { get { return items; } }
        }

        public static void Main()
        {

           DeserializeFromXML();
            Console.WriteLine();
        }

        static public void SerializeToXML(MyWrapper list)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(MyWrapper));
            using (TextWriter textWriter = new StreamWriter(@"Employees.xml"))
            {
                serializer.Serialize(textWriter, list);
                textWriter.Close();
            }
        }

        static public void DeserializeFromXML()
        {
            Employee employees = null;
            string path = "test.xml";

            XmlRootAttribute root = new XmlRootAttribute();
            root.ElementName = "Employee";

            XmlSerializer serializer = new XmlSerializer(typeof(List<Employee>));

            StreamReader reader = new StreamReader(path);
//Exception on xml(2,2) file 
            employees = (Employee)serializer.Deserialize(reader);
            reader.Close();
        }
    }

请,帮助

3 个答案:

答案 0 :(得分:0)

问题是您要序列化MyWrapper对象:

XmlSerializer serializer = new XmlSerializer(typeof(MyWrapper));

但尝试反序列化员工列表:

XmlSerializer serializer = new XmlSerializer(typeof(List<Employee>));

您需要使用与序列化相同类型的序列化程序。

编辑:尝试反序列化您的xml示例后,它对我不起作用,因此我冒昧地更改数据协定以正确反序列化文件:

   [XmlRoot("Employees")]
    public class MyWrapper
    {
        public List<Employee> Items { get; set; }
    }

    [XmlRoot("Employee")]
     public class Employee
    {
        public string FirstNameP
        {get;set;}
        public string LastNameP
        {get;set;}
        public int AgeP
        {get;set;}
        public string DepartmentP
        {get;set;}
        public string AddressP
        {get; set;}
    }

答案 1 :(得分:0)

如果序列化MyWrapper,则必须反序列化static public void DeserializeFromXML () { // changed to be a list of employees List<Employee> employees = null; // added MyWrapper wrapper = null; string path = "test.xml"; // changed type to MyWrapper XmlSerializer serializer = new XmlSerializer (typeof(MyWrapper)); StreamReader reader = new StreamReader(path); // changed type to MyWrapper wrapper = (MyWrapper)serializer.Deserialize(reader); reader.Close(); employees = wrapper.Items; } ,而不是列表&lt;员工&gt;。您始终必须反序列化与序列化相同的类型。

我稍微改了你DeserializeFromXML:

static public List<Employee> DeserializeFromXML()
{
    MyWrapper wrapper = null;
    string path = "Employees.xml";

    XmlSerializer serializer = new XmlSerializer(typeof(MyWrapper));

    using (StreamReader reader = new StreamReader(path)) {
        wrapper = (MyWrapper)serializer.Deserialize (reader);
    }

    return wrapper.Items;
}

<强> Impoved

它反序列化您的数据并返回员工列表。它还使用using statement来确保StreamReader在超出范围时被处置。

[XmlRoot("Employee")]

您的数据类

还需要一些小的改动。我使用了Auto-Implemented Proeperties并删除了未使用的成员。我删除了属性public class Employee { string firstName; public string FirstNameP { get { return firstName; } set { firstName = value; } } public string LastNameP { get; set; } public int AgeP { get; set; } public string DepartmentP { get; set; } public string AddressP{ get; set; } } [XmlRoot("Employees")] public class MyWrapper { private List<Employee> items = new List<Employee> (); public List<Employee> Items { get { return items; } set { items = value;} } } ,因为如果它与类的名称值相同,则它已过时。

def change_str(str)
  str.replace 'goodbye'
end

str = 'hello'
change_str(str)
puts str
#=> goodbye

答案 2 :(得分:0)

[XmlRoot("Employees")]
    [Serializable]
    public class MyWrapper
    {
        [XmlElement("Employee")]
        public List<Employee> Items { get; set; }
        public MyWrapper()
        {
            Items = new List<Employee>();
        }

    }

    public class Selection
    {
        [XmlIgnore]
        MyWrapper wrap = new MyWrapper();

        [XmlElement("Employee")]
        public IEnumerable<Employee> Items { get; set; }
        public IEnumerable<Employee> AgeSelection()
        {
            Items = wrap.Items.Where(x => x.AgeP > 25);
            return Items;
        }
    }

    public static void Main()
    {
        var wrapper = new MyWrapper();

        string[] firstNames = { "Vlad", "Alexey", "Dmitriy" };
        string[] lastNames = { "Ogirenko", "Belous", "Ivanov" };
        int[] ages = { 19, 26, 33 };
        string[] departments = { ".Net Sharepoint", "Network", ".Net Sharepoint" };
        string[] address = { "Kharkov", "Kharkov", "Donetsk" };


        for (int i = 0; i < 3; i++)
        {
            Employee em = new Employee();
            em.FirstNameP = firstNames[i];
            em.LastNameP = lastNames[i];
            em.AgeP = ages[i];
            em.DepartmentP = departments[i];
            em.AddressP = address[i];
            wrapper.Items.Add(em);
            object o = typeof(Employee).GetField("EmpoyeeID", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(em);
        }

        SerializeToXML(wrapper, "test.xml");

        wrapper = DeserializeFromXML();
        foreach (var el in wrapper.Items)
        {
            ChangeEmployeeId(el, el.FirstNameP, el.LastNameP);
            Console.WriteLine("#"+(wrapper.Items.IndexOf(el)+1));
            Console.WriteLine("EmployeeID: "+GetId(el));
            Console.Write(el.Show()+"\n");
            Console.WriteLine("Address: "+GetAddress(el)+"\n");
        }

        Selection select = new Selection();

        SerializeToXML(select.AgeSelection(),"22.xml");
        Console.ReadLine();
    }

    static public void SerializeToXML(object list,string path)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(MyWrapper));

        using (var stream = new FileStream(path, FileMode.Create))
        {
            serializer.Serialize(stream, list);
            stream.Flush();
            stream.Close();
        }
    }

    static public MyWrapper DeserializeFromXML()
    {

        List<Employee> employees = null;
        MyWrapper wrapper = null;
        XmlSerializer serializer = new XmlSerializer(typeof(MyWrapper));

        string path = "test.xml";

        var stream = new FileStream(path, FileMode.Open);

        wrapper = (MyWrapper)serializer.Deserialize(stream);
        stream.Close();

        employees = wrapper.Items;

        return wrapper;
    }