1. Введение
XML — аббревиатура от eXtensible Markup Language. Представьте себе очень строгого и разговорчивого JSON, способного много раз повторять «я структурированный, поверь мне!». XML — текстовый формат, в котором данные обрамляются тегами:
<Player>
<Name>Aragorn</Name>
<Health>100</Health>
</Player>
Зачем нам сериализовать объекты в XML в наши дни?
- XML продолжает широко применяться в интеграции между крупными (часто «легаси») системами, где требуется не только структура, но и валидация по строгим схемам (XSD).
- XML часто используют в корпоративных конфигурациях (например, App.config и Web.config в .NET старых поколений).
- XML идеально ложится на задачи, где важна «самоописываемость» структуры данных.
Интересный факт: XML изначально проектировался так, чтобы быть как можно более «расширяемым» и валидируемым; отсюда и его название. Его можно проверить на соответствие схеме, чего до сих пор нет у JSON «из коробки».
XmlSerializer: главный герой
В .NET за сериализацию объектов в XML отвечает класс System.Xml.Serialization.XmlSerializer.
- Он превращает публичные свойства и поля объекта в элементы XML, и наоборот: по XML восстанавливает объект.
- Работает только с открытыми типами и членами классов.
- Не сериализует приватные поля и свойства — только то, что публично!
- Требует для работы наличия пустого конструктора у сериализуемого класса.
Обратите внимание: Если ваш класс не соответствует этим требованиям, XmlSerializer просто не сможет с ним работать — выдаст исключение на этапе сериализации или десериализации.
2. Простой пример — сериализация объекта в XML
Давайте рассмотрим, как сериализовать наш любимый класс Player в XML.
Шаг 1. Описываем класс
public class Player
{
public string Name { get; set; }
public int Health { get; set; }
public bool IsAlive { get; set; }
// Важно: нужен публичный конструктор без параметров!
public Player() { }
// Опционально: для удобства
public Player(string name, int health, bool isAlive)
{
Name = name;
Health = health;
IsAlive = isAlive;
}
}
Шаг 2. Сериализуем в файл
using System.Xml.Serialization;
Player aragorn = new Player("Aragorn", 100, true);
// 1. Создаём сериализатор для типа Player
XmlSerializer serializer = new XmlSerializer(typeof(Player));
// 2. Открываем файл для записи (создастся, если не существует)
using FileStream fs = new FileStream("player.xml", FileMode.Create);
// 3. Сериализуем объект в XML
serializer.Serialize(fs, aragorn);
Результат (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>
Визуальная схема простейшего процесса
Объект в памяти ---> XmlSerializer.Serialize() ---> XML-файл на диске
3. Десериализация — «оживляем» объект из XML
Когда нам нужно прочитать сериализованный ранее объект, процесс обратный:
using FileStream fs = new FileStream("player.xml", FileMode.Open);
XmlSerializer serializer = new XmlSerializer(typeof(Player));
Player player = (Player)serializer.Deserialize(fs);
Console.WriteLine($"Имя: {player.Name}, Здоровье: {player.Health}, Жив: {player.IsAlive}");
В результате программа выдаст: Имя: Aragorn, Здоровье: 100, Жив: True
4. Сериализация в строку — не только в файл
Сериализация в строку
Не всегда хочется сериализовать объект в файл. Иногда, например, нужно передать XML как строку по сети или показать на экране.
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); // Вся строка XML — на экране!
Десериализация из строки
Аналогично можно десериализовать объект не из файла, а из строки:
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. Кастомизация XML: атрибуты для управления структурой
Иногда стандартное поведение вас не устраивает. XML получается слишком многословным или теги не совпадают с целевыми. На помощь приходят различные «магические» атрибуты — прямо указывают сериализатору, как представлять члены класса.
Самые полезные:
— называет элемент.[XmlElement]
— делает поле атрибутом XML, а не элементом.[XmlAttribute]
— исключает свойство из сериализации.[XmlIgnore]
и[XmlArray]
— управляют упаковкой коллекций.[XmlArrayItem]
Пример использования:
public class Player
{
[XmlAttribute]
public string Name { get; set; }
[XmlElement("HP")]
public int Health { get; set; }
[XmlIgnore]
public bool IsTempSessionPlayer { get; set; }
}
Результирующий XML:
<Player Name="Aragorn">
<HP>100</HP>
</Player>
Таблица основных атрибутов для сериализации
| Атрибут | На что влияет | Пример использования |
|---|---|---|
|
Превращает свойство в атрибут XML | |
|
Меняет имя тега | вместо |
|
Полностью исключает свойство из сериализации | — |
|
Меняет имя "обёртки" коллекции | |
|
Меняет имя элемента коллекции | |
Пример сложной сериализации коллекции:
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>
Подробнее о кастомизации XML вы узнаете в следующих лекциях! :P
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ