In .NET framework, the namespace System.Xml.Serialization provides all the necessary functionality to help convert a "Serializable" object into stream of bytes and then System.IO helps with all the necessary tools to write those stream of bytes into a physical file.
Here is an example where we serialize an object into a stream and then save the stream into a physical XML
Model classes: First we will create a few simple classes which we want to be represented in form of an XML
public class University { public University() { } public string Name { get; set; } public string Address { get; set; } public short Rating { get; set; } public List<Institute> AffiliatedInstitutes = new List<Institute>(); } public class Institute { public Institute() { } public string Name { get; set; } public string Address { get; set; } public short Rating { get; set; } public List<Student> Students = new List<Student>(); } public class Course { public Course() { } public string Name { get; set; } public short DurationInMonths { get; set; } public string CourseType { get; set; } } public class Student { public Student() { } public string FirstName { get; set; } public string LastName { get; set; } public string Address { get; set; } public string EnrollmentNumber { get; set; } public Course Course { get; set; } }
In the example above, we are going to serialize the class University which must include properties of all the types (Institute, Course, Student). To enable these classes to be serialized we need to decorate them with some attributes. Lets take a look at the definitions of same classes-
using System.Collections.Generic; using System.Xml.Serialization; using System.IO; using System; ... [XmlRoot()] public class University { public University() { } public string Name { get; set; } public string Address { get; set; } public short Rating { get; set; } public List<Institute> AffiliatedInstitutes = new List<Institute>(); } [XmlInclude(typeof(Institute))] public class Institute { public Institute() { } public string Name { get; set; } public string Address { get; set; } public short Rating { get; set; } public List<Student> Students = new List<Student>(); } [XmlInclude(typeof(Course))] public class Course { public Course() { } public string Name { get; set; } public short DurationInMonths { get; set; } public string CourseType { get; set; } } [XmlInclude(typeof(Student))] public class Student { public Student() { } public string FirstName { get; set; } public string LastName { get; set; } public string Address { get; set; } public string EnrollmentNumber { get; set; } public Course Course { get; set; } }
In the class definitions above, there are a few things worth noticing.
XmlRoot() attribute: The class definition following this attribute is chosen to be the root node of the finally serialized XML.
XmlInclude(TYPE) attribute: The class definitions following this attribute are marked to be serialized, if there exist any class member of its type in the root object.
By default all the unmarked properties of a class are treated as child elements of parent object(XmlElement). If we want a property to appear like an attribute of its parent node, we need to add an attribute XmlAttribute("attributeName").
Finally we define a method in our University class which actually does the job to convert an object of its own type into stream of bytes (i.e. serializes its object) and then writes those stream of bytes to a physical fine.
public class University { public University() {} public string Name { get; set; } public string Address { get; set; } public short Rating { get; set; } public List<Institute> AffiliatedInstitutes = new List<Institute>(); public bool SaveToXML(string filePath) { try { //Instantiate an object of XmlSerializer class specifying the root object type (i.e. University) XmlSerializer serializer = new XmlSerializer(typeof(University)); //Instantiate an object of memory stream which we will use as a continer for the serialized stream MemoryStream ms = new MemoryStream(); using (ms) { //Run Serialize method on current instance of University class serializer.Serialize(ms, this); //Read the memory stream into a string object, //though we don't need to read it but we will do so, so that we can debug it and see the XML first before we write it ms.Position = 0; string data = string.Empty; StreamReader reader = new StreamReader((Stream) ms); using (reader) { data = reader.ReadToEnd(); } //Now write the string to the specified path File.WriteAllText(filePath, data); reader.Dispose(); return true; } } catch (Exception) { return false; } } }Now, lets test the code above-
static void Main(string[] args) { Course mastersBusiness = new Course() { CourseType = "PG-Degree", DurationInMonths = 24, Name = "Masters of Business Administration" }; Course bachelorEngineering = new Course() { CourseType = "Graguate-Degree", DurationInMonths = 48, Name = "Bachelor of Engineering" }; Student steveRichards = new Student() { FirstName = "Steve", LastName = "Richards", Course = bachelorEngineering, Address = string.Empty, EnrollmentNumber = "BE20111234" }; Student davidBaker = new Student() { FirstName = "David", LastName = "Baker", Course = mastersBusiness, Address = string.Empty, EnrollmentNumber = "MB20111234" }; Institute rafaelInstitute = new Institute() { Name = "St. Rafael Institute for Higher Studies", Address = "123, Orleans Dr., Santa Clara, CA 94902", Rating = 3 }; rafaelInstitute.Students.Add(steveRichards); rafaelInstitute.Students.Add(davidBaker); University testUniversity = new University() { Name = "State University of California", Address = "Palo Alto, CA, 92033", Rating = 5 }; testUniversity.AffiliatedInstitutes.Add(rafaelInstitute); testUniversity.SaveToXML(@"F:\" + testUniversity.Name + ".xml"); }
When we are good so far, here is the XML you should already have written somewhere on your disk-
<?xml version="1.0"?> <University xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <AffiliatedInstitutes> <Institute> <Students> <Student> <FirstName>Steve</FirstName> <LastName>Richards</LastName> <Address /> <EnrollmentNumber>BE20111234</EnrollmentNumber> <Course> <Name>Bachelor of Engineering</Name> <DurationInMonths>48</DurationInMonths> <CourseType>Graguate-Degree</CourseType> </Course> </Student> <Student> <FirstName>David</FirstName> <LastName>Baker</LastName> <Address /> <EnrollmentNumber>MB20111234</EnrollmentNumber> <Course> <Name>Masters of Business Administration</Name> <DurationInMonths>24</DurationInMonths> <CourseType>PG-Degree</CourseType> </Course> </Student> </Students> <Name>St. Rafael Institute for Higher Studies</Name> <Address>123, Orleans Dr., Santa Clara, CA 94902</Address> <Rating>3</Rating> </Institute> </AffiliatedInstitutes> <Name>State University of California</Name> <Address>Palo Alto, CA, 92033</Address> <Rating>5</Rating> </University>
Awesome logic! Thanks for sharing this with me!
ReplyDeletehp 1020 driver
Glad that you liked it.
ReplyDelete