Search code examples
c#xml-serialization

Serializing a class under a different element name


I have this class:

[XmlRoot(ElementName ="Lesson")]
public class LessonOld
{
    public LessonOld()
    {
        Students = new List<string>();
    }
    public string Name { get; set; }
    public DateTime FirstLessonDate { get; set; }
    public int DurationInMinutes { get; set; }
    public List<string> Students { get; set; }
}

And I'm using this code to serialize it:

TextWriter writer = new StreamWriter(Path.Combine(UserSettings, "Lessons-temp.xml"));
XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<LessonOld>));
xmlSerializer.Serialize(writer, tempList);
writer.Close();

(Note that that is a List<LessonOld>)

Here is my resulting XML:

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfLessonOld xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <LessonOld>
    <FirstLessonDate>0001-01-01T00:00:00</FirstLessonDate>
    <DurationInMinutes>0</DurationInMinutes>
    <Students />
  </LessonOld>
</ArrayOfLessonOld>

I would like to change it to serialize as <ArrayOfLesson and <Lesson> for the XML elements. Is this possible? (As you can see, I've already tried using [XmlRoot(ElementName ="Lesson")])


Solution

  • You're almost there. Use:

    [XmlType(TypeName = "Lesson")]
    

    instead of

    [XmlRoot(ElementName = "Lesson")]
    

    Of course you can test it easily; your code with the above change

    [XmlType(TypeName = "Lesson")]
    public class LessonOld
    {
        public LessonOld()
        {
            Students = new List<string>();
        }
        public string Name { get; set; }
        public DateTime FirstLessonDate { get; set; }
        public int DurationInMinutes { get; set; }
        public List<string> Students { get; set; }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            TextWriter writer = new StreamWriter(Path.Combine(@"C:\Users\Francesco\Desktop\nanovg", "Lessons-temp.xml"));
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<LessonOld>));
            xmlSerializer.Serialize(writer, new List<LessonOld> { new LessonOld() { Name = "name", DurationInMinutes = 0 } });
            writer.Close();
        }
    }
    

    produces this

    <?xml version="1.0" encoding="utf-8"?>
    <ArrayOfLesson xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <Lesson>
        <Name>name</Name>
        <FirstLessonDate>0001-01-01T00:00:00</FirstLessonDate>
        <DurationInMinutes>0</DurationInMinutes>
        <Students />
      </Lesson>
    </ArrayOfLesson>
    

    As I've seen it, XmlRoot works fine when you want to serialize a single object. Consider this code, derived from yours:

    [XmlRoot(ElementName = "Lesson")]
    public class LessonOld
    {
        public LessonOld()
        {
            Students = new List<string>();
        }
        public string Name { get; set; }
        public DateTime FirstLessonDate { get; set; }
        public int DurationInMinutes { get; set; }
        public List<string> Students { get; set; }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            TextWriter writer = new StreamWriter(Path.Combine(@"C:\Users\Francesco\Desktop\nanovg", "Lessons-temp.xml"));
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(LessonOld));
            xmlSerializer.Serialize(writer, new LessonOld() { Name = "name", DurationInMinutes = 0  });
            writer.Close();
        }
    }
    

    It will output

    <?xml version="1.0" encoding="utf-8"?>
    <Lesson xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <Name>name</Name>
      <FirstLessonDate>0001-01-01T00:00:00</FirstLessonDate>
      <DurationInMinutes>0</DurationInMinutes>
      <Students />
    </Lesson>