como-serializar-y-deserializar-ficheros-xml-en-c

How to serialize and deserialize XML files in C#

  • 4 min

In this post, we are going to see how to serialize and deserialize an object to an XML file in C#.

We previously 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 where it is interesting to be able to generate or read them.

Fortunately, working with XML files in C# is extremely easy, and it is not necessary to use third-party libraries since the necessary tools are integrated into .NET itself.

So, let’s assume 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>();
}
Copied!

Which, in turn, contains a collection of the following class.

public class mySubItem
{
  public string SubText { get; set; }
  public int SubNumber { get; set; }
}
Copied!

First Solution

Serializing an object to an XML file, or the opposite, 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;
  }
}
Copied!

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 make the code even simpler and more reusable if we convert these functions into generic functions, so they work with any class.

In this way, the necessary code to work with XML files for any class would look like 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<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;
  }
}
Copied!

With Extension Methods

Finally, if we extract these generic methods to an external file as extension methods, the code becomes even simpler and more reusable, ending up like this.

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

Which would be used like this

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

We can add these methods to our collection of extension classes to work easily and comfortably with XML files in .NET.