1. Introduction
XML — abbreviation for eXtensible Markup Language. Imagine a very strict and talkative JSON that can repeat "I'm structured, trust me!" many times. XML is a text format where data is wrapped in tags:
<Player>
<Name>Aragorn</Name>
<Health>100</Health>
</Player>
Why would we serialize objects to XML nowadays?
- XML is still widely used for integration between large (often "legacy") systems where not only structure but validation against strict schemas (XSD) is required.
- XML is often used in enterprise configuration (for example, App.config and Web.config in older .NET generations).
- XML fits perfectly for tasks where the "self-describing" nature of the data structure matters.
Fun fact: XML was originally designed to be as "extensible" and validatable as possible — hence the name. You can validate it against a schema, which JSON doesn't have out of the box.
XmlSerializer: the main character
In .NET the class responsible for serializing objects to XML is System.Xml.Serialization.XmlSerializer.
- It turns public properties and fields of an object into XML elements, and vice versa: reconstructs an object from XML.
- Works only with open/public types and class members.
- Doesn't serialize private fields and properties — only what's public!
- Requires a parameterless constructor on the serializable class to work.
Note: If your class doesn't meet these requirements, XmlSerializer simply won't be able to handle it — it will throw an exception during serialization or deserialization.
2. Simple example — serializing an object to XML
Let's see how to serialize our favorite class Player to XML.
Step 1. Describe the class
public class Player
{
public string Name { get; set; }
public int Health { get; set; }
public bool IsAlive { get; set; }
// Important: a public parameterless constructor is required!
public Player() { }
// Optional: for convenience
public Player(string name, int health, bool isAlive)
{
Name = name;
Health = health;
IsAlive = isAlive;
}
}
Step 2. Serialize to a file
using System.Xml.Serialization;
Player aragorn = new Player("Aragorn", 100, true);
// 1. Create a serializer for the Player type
XmlSerializer serializer = new XmlSerializer(typeof(Player));
// 2. Open a file for writing (will be created if it doesn't exist)
using FileStream fs = new FileStream("player.xml", FileMode.Create);
// 3. Serialize the object to XML
serializer.Serialize(fs, aragorn);
Result (player.xml):
<?xml version="1.0"?>
<Player xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Name>Aragorn</Name>
<Health>100</Health>
<IsAlive>true</IsAlive>
</Player>
Visual diagram of the simplest process
Object in memory ---> XmlSerializer.Serialize() ---> XML file on disk
3. Deserialization — "reviving" an object from XML
When we need to read a previously serialized object, the process is the reverse:
using FileStream fs = new FileStream("player.xml", FileMode.Open);
XmlSerializer serializer = new XmlSerializer(typeof(Player));
Player player = (Player)serializer.Deserialize(fs);
Console.WriteLine($"Name: {player.Name}, Health: {player.Health}, IsAlive: {player.IsAlive}");
The program will output: Name: Aragorn, Health: 100, IsAlive: True
4. Serialization to a string — not only to a file
Serialize to a string
You don't always want to serialize an object to a file. Sometimes you need to send XML as a string over the network or display it on screen.
using System.IO;
using System.Xml.Serialization;
Player player = new Player("Frodo", 42, true);
XmlSerializer serializer = new XmlSerializer(typeof(Player));
StringWriter stringWriter = new StringWriter();
serializer.Serialize(stringWriter, player);
string xmlString = stringWriter.ToString();
Console.WriteLine(xmlString); // The whole XML string — on the screen!
Deserialize from a string
Similarly you can deserialize an object not from a file but from a string:
string xml = "<Player Name=\"Frodo\"><HP>42</HP></Player>";
XmlSerializer serializer = new XmlSerializer(typeof(Player));
using StringReader stringReader = new StringReader(xml);
Player frodo = (Player)serializer.Deserialize(stringReader);
Console.WriteLine(frodo.Name); // Frodo
5. Customizing XML: attributes to control structure
Sometimes the default behavior doesn't cut it. The XML can be too verbose or tags don't match the target. Various "magic" attributes help — they tell the serializer exactly how to represent class members.
Most useful ones:
— names an element.[XmlElement]
— makes a field an XML attribute instead of an element.[XmlAttribute]
— excludes a property from serialization.[XmlIgnore]
and[XmlArray]
— control collection wrapping.[XmlArrayItem]
Usage example:
public class Player
{
[XmlAttribute]
public string Name { get; set; }
[XmlElement("HP")]
public int Health { get; set; }
[XmlIgnore]
public bool IsTempSessionPlayer { get; set; }
}
Resulting XML:
<Player Name="Aragorn">
<HP>100</HP>
</Player>
Table of main attributes for serialization
| Attribute | What it affects | Usage example |
|---|---|---|
|
Turns a property into an XML attribute | |
|
Changes the tag name | instead of |
|
Completely excludes the property from serialization | — |
|
Changes the name of the collection "wrapper" | |
|
Changes the name of the collection item | |
Example of complex collection serialization:
public class GameWorld
{
[XmlArray("Heroes")]
[XmlArrayItem("Hero")]
public List<Player> Players { get; set; } = new List<Player>();
}
XML:
<GameWorld>
<Heroes>
<Hero Name="Legolas">
<HP>90</HP>
</Hero>
<!-- ... -->
</Heroes>
</GameWorld>
You'll learn more about customizing XML in the following lectures! :P
GO TO FULL VERSION