JavaRush /Курсы /C# SELF /Работа с XmlSerializer

Работа с XmlSerializer для сериализации в XML

C# SELF
44 уровень , 2 лекция
Открыта

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]
    — называет элемент.
  • [XmlAttribute]
    — делает поле атрибутом XML, а не элементом.
  • [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>

Таблица основных атрибутов для сериализации

Атрибут На что влияет Пример использования
[XmlAttribute]
Превращает свойство в атрибут XML
<Player Name="Aragorn">...</Player>
[XmlElement]
Меняет имя тега
<HP>100</HP>
вместо
<Health>100</Health>
[XmlIgnore]
Полностью исключает свойство из сериализации
[XmlArray]
Меняет имя "обёртки" коллекции
<Heroes> ... </Heroes>
[XmlArrayItem]
Меняет имя элемента коллекции
<Hero>...</Hero>

Пример сложной сериализации коллекции:

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

2
Задача
C# SELF, 44 уровень, 2 лекция
Недоступна
Сериализация и десериализация списка объектов
Сериализация и десериализация списка объектов
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ