In this post, we will see how to serialize and deserialize an object to an XML file in C#.
We already saw how to work with Json files comfortably in .NET thanks to the JsonNET library. JSON files have become the preferred standard for exchanging data between applications, especially in web environments.
However, the XML format is still widely used, and there are many situations in which it is interesting to be able to generate or read them.
Fortunately, working with XML files in C# is extremely simple, and it is not necessary to use third-party libraries as the necessary tools are integrated into .NET itself.
So, suppose we want to work with the following example class.
public class myItem
{
public string Text { get; set; }
public int Number { get; set; }
public double Decimal { get; set; }
public List<mySubItem> SubItems { get; set; } = new List<mySubItem>();
}
Which, in turn, contains a collection of the following class.
public class mySubItem
{
public string SubText { get; set; }
public int SubNumber { get; set; }
}
First solution
Serializing an object to an XML file, or conversely, deserializing an XML file to an object, is as simple as the following.
static void Main(string[] args)
{
var item = new myItem
{
Text = "A",
Number = 10,
Decimal = 20.5,
SubItems =
{
new mySubItem {SubText = "A.A", SubNumber = 100},
new mySubItem {SubText = "A.B", SubNumber = 200},
new mySubItem {SubText = "A.C", SubNumber = 300},
}
};
saveToXML(item, "export.xml");
var newItem = loadFromXML("export.xml");
}
public static void saveToXML(myItem item, string path)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(myItem));
using (var writer = XmlWriter.Create(path, new XmlWriterSettings { Indent = true }))
{
xmlSerializer.Serialize(writer, item);
}
}
public static myItem loadFromXML(string path)
{
var xmlSerializer = new XmlSerializer(typeof(myItem));
using (var reader = XmlReader.Create(path))
{
return xmlSerializer.Deserialize(reader) as myItem;
}
}
Where, as we can see, we have used two methods ‘saveToXML’ and ‘loadFromXML’ to perform serialization and deserialization respectively to our example class ‘myItem’.
With generic methods
We can still make the code simpler and more reusable by converting these functions into generic functions, so that they work with any class.
This way, the code needed to work with XML files for any class would be as follows.
static void Main(string[] args)
{
var item = new myItem
{
Text = "A",
Number = 10,
Decimal = 20.5,
SubItems =
{
new mySubItem {SubText = "A.A", SubNumber = 100} ,
new mySubItem {SubText = "A.B", SubNumber = 200} ,
new mySubItem {SubText = "A.C", SubNumber = 300} ,
}
};
saveToXML(item, "export.xml");
var newItem = loadFromXML<myItem>("export.xml");
}
public static void saveToXML<T>(T item, string path)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
using (var writer = XmlWriter.Create(path, new XmlWriterSettings { Indent = true }))
{
xmlSerializer.Serialize(writer, item);
}
}
public static T loadFromXML<T>(string path) where T: class
{
var xmlSerializer = new XmlSerializer(typeof(T));
using (var reader = XmlReader.Create(path))
{
return xmlSerializer.Deserialize(reader) as T;
}
}
With extension methods
Finally, if we extract these general methods to an external file as extension methods, the code becomes even simpler and reusable, as follows.
public static class Extensions
{
public static void SerializeToXml<T>(this T instance, string filename) where T : class, new()
{
var serializer = new XmlSerializer(typeof(T));
using (var stream = new FileStream(filename, FileMode.Create, FileAccess.Write))
{
serializer.Serialize(stream, instance);
}
}
public static T DeserializeFromXml<T>(this string filePath) where T : class, new()
{
using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
stream.Position = 0;
var serializer = new XmlSerializer(typeof (T));
return serializer.Deserialize(stream) as T;
}
}
}
Which would be used as follows
class Program
{
static void Main(string[] args)
{
var item = new myItem
{
Text = "A",
Number = 10,
Decimal = 20.5,
SubItems =
{
new mySubItem {SubText = "A.A", SubNumber = 100} ,
new mySubItem {SubText = "A.B", SubNumber = 200} ,
new mySubItem {SubText = "A.C", SubNumber = 300} ,
}
};
item.SerializeToXml("export.xml");
var newItem = "export.xml".DeserializeFromXml<myItem>();
}
}
We can add these methods to our collection of extension classes to work easily and conveniently with XML files in .NET.