How to deserialize collection from this xml?

143 views Asked by At

****I serialize my Employee collection on xml file. When i try to deserialize collection from that or another them program throws exception: An unhandled exception of type "System.InvalidOperationException" in System.Xml.dll For more information : The document XML ( 2 , 2 ) there is an error . XML file:

`

<?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>`

Code:

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

please, help

3

There are 3 answers

0
Vlad Agurets On
[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;
    }
0
Alioza On

A problem is that you're serializing a MyWrapper object:

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

but trying to deserialize a list of employees:

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

You need to use a serializer for the same type you used to serialize.

EDIT: Having tried to deserialize your xml sample it did not work for me so I took the liberty of changing the data contract to deserialize the file correctly:

   [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;}
    }
4
devmb On

If you serialize MyWrapper, you have to deserialize MyWrapper, not List< Employee >. You always have to deserialize the same type as you serialize.

I changed you DeserializeFromXML a bit:

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;
}

Impoved

It deserializes your the data and returns a List of employees. It also uses a using statement to make sure the StreamReader is disposed if it's out of scope.

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;
}

Your data classes

need also a few minor changes. I used Auto-Implemented Proeperties and removed the unused members. I removed the Attribute [XmlRoot("Employee")] cause it's obsolete if it's the same value as the name of the class.

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;}
    }
}