0

I have this Student class and want to save a list of Student (List students) to XML file as well as read them back from the same XML file to a List of Student. Below shows the function doing the job but only with a single Student object? What should I do to make it work with a List instead?

using System;
using System.IO;
using System.Xml.Serialization;
namespace P02_Xml
{
    public class Student
    {
        public int Id { get; set; } = 1;
        public string FirstName { get; set; } = "";
        public string LastName { get; set; } = "";
        public DateTime DateOfBirth { get; set; } = DateTime.Now;
    }
    class Program
    {
        static void Main(string[] args)
        {
            var student = new Student
            {
                Id = 1,
                FirstName = "Nguyen Van",
                LastName = "A",
                DateOfBirth = new DateTime(1990, 12, 30)
            };
            Console.WriteLine("Original object:");
            Print(student);
            Save(student);
            var nva = Load();
            Console.WriteLine("Deserialized object:");
            Print(nva);
            Console.ReadKey();
        }
        static void Print(Student student)
        {
            Console.WriteLine($"Id: {student.Id}\r\nFirst Name: {student.FirstName}\r\nLast Name: {student.LastName}\r\nDate of birth: {student.DateOfBirth.ToShortDateString()}");
        }
        static void Save(Student student)
        {
            using (var stream = File.OpenWrite("data.xml"))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(Student));
                serializer.Serialize(stream, student);
            }
        }
        static Student Load()
        {
            Student student;
            using (var stream = File.OpenRead("data.xml"))
            {
                var serializer = new XmlSerializer(typeof(Student));
                student = serializer.Deserialize(stream) as Student;
            }
            return student;
        }
    }
}
1
  • 2
    Do you have to use XmlSerializer? Personally I've usually found that to be more trouble than it's worth - whereas using LINQ to XML and including conversion methods to/from XML in the classes themselves (e.g. Student in this case) is pretty straightforward. Commented Jun 1, 2022 at 6:55

1 Answer 1

1

Based on the code that you have the simplest thing is this:

    static void Save(IEnumerable<Student> students)
    {
        using (var stream = File.OpenWrite("data.xml"))
        {
            XmlSerializer serializer = new XmlSerializer(typeof(Student[]));
            serializer.Serialize(stream, students.ToArray());
        }
    }

    static Student[] Load()
    {
        Student[] student;
        using (var stream = File.OpenRead("data.xml"))
        {
            var serializer = new XmlSerializer(typeof(Student[]));
            student = serializer.Deserialize(stream) as Student[];
        }
        return student;
    }

Now you can do this:

var students = new[]
{
    new Student
    {
        Id = 1,
        FirstName = "Nguyen Van",
        LastName = "A",
        DateOfBirth = new DateTime(1990, 12, 30)
    },
    new Student
    {
        Id = 2,
        FirstName = "Fred",
        LastName = "Nerk",
        DateOfBirth = new DateTime(1990, 12, 30)
    }
};

Save(students);

And load & print like this:

        var nva = Load();

        foreach (var student in nva)
            Print(student);

As Jon Skeet says, XmlSerializer is more trouble than it's worth. I tend to do it this way:

public class Student
{
    public int Id { get; set; } = 1;
    public string FirstName { get; set; } = "";
    public string LastName { get; set; } = "";
    public DateTime DateOfBirth { get; set; } = DateTime.Now;

    public static Student[] FromXDocument(string fileName) =>
        Student.FromXDocument(XDocument.Load(fileName));

    public static Student[] FromXDocument(XDocument document) =>
        document
            .Root
            .Elements("Student")
            .Select(element => new Student()
            {
                Id = (int)element.Attribute("Id"),
                FirstName = element.Attribute("FirstName").Value,
                LastName = element.Attribute("LastName").Value,
                DateOfBirth = (DateTime)element.Attribute("DateOfBirth"),
            })
            .ToArray();

    public static XDocument ToXDocument(IEnumerable<Student> students) =>
        new XDocument(
            new XElement(
                "Students",
                students
                    .Select(student =>
                    new XElement(
                        "Student",
                        new XAttribute("Id", student.Id),
                        new XAttribute("FirstName", student.FirstName),
                        new XAttribute("LastName", student.LastName),
                        new XAttribute("DateOfBirth", student.DateOfBirth)))));
}

Then use it like this:

        Student.ToXDocument(students).Save("students.xml");

        var nva = Student.FromXDocument("students.xml");
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.