XmlSerializer

21

В дополнение к двоичному форматеру и форматеру SOAP сборка System.Xml.dll предлагает третий класс форматера — System.Xml.Serialization.XmlSerializer — который может использоваться для сохранения общедоступного состояния заданного объекта в виде чистой XML-разметки, в противоположность данным XML внутри сообщения SOAP. Работа с этим типом несколько отличается от работы с типами SoapFormatter или BinaryFormatter. Рассмотрим следующий код (предполагается, что было импортировано пространство имен System.Xml.Serialization):

static void SaveInXmlFormat(object objGraph, string fileName)
    {
            XmlSerializer xmlFormat = new XmlSerializer(typeof(JamesBondClass),
                new Type[] { typeof(Radio), typeof(Car) });
            using (Stream fStream = new FileStream(fileName,
                FileMode.Create, FileAccess.Write, FileShare.None))
                {
                    xmlFormat.Serialize(fStream, objGraph);
                }
            Console.WriteLine("--> Сохранение объекта в XML-формат");
    }

Ключевое отличие состоит в том, что тип XmlSerializer требует указания информации о типе, представляющей класс, который необходимо сериализовать. В сгенерированном файле XML находятся показанные ниже данные XML:

<?xml version="1.0"?>
<JamesBondClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <theRadio>
    <hasTweeters>true</hasTweeters>
    <hasSubWoofers>false</hasSubWoofers>
    <stationPresets>
      <double>89.3</double>
      <double>105.1</double>
      <double>97.1</double>
    </stationPresets>
    <radioID>XF-552RF6</radioID>
  </theRadio>
  <isHatchBack>false</isHatchBack>
  <canFly>true</canFly>
  <canSubmerge>false</canSubmerge>
</JamesBondClass>

Класс XmlSerializer требует, чтобы все сериализованные типы в графе объектов поддерживали конструктор по умолчанию (поэтому не забудьте его добавить, если определяли специальные конструкторы). Если этого не сделать, во время выполнения сгенерируется исключение InvalidOperationException.

Если у вас есть опыт в технологиях XML, то вы хорошо знаете, насколько важно удостоверяться, что данные внутри документа XML отвечают набору правил, которые устанавливают действительность данных. Понятие "действительного" документа XML не имеет отношения к синтаксической правильности элементов XML (вроде того, что все открывающие элементы должны иметь соответствующие закрывающие элементы).

Действительные документы — это те, что отвечают согласованным правилам форматирования (например, поле X должно быть выражено как атрибут, но не как подэлемент), которые обычно определены схемой XML или в файле определения типа документа (Document-Type Definition — DTD).

По умолчанию класс XmlSerializer сериализует все общедоступные поля/свойства как элементы XML, а не как атрибуты XML. Чтобы управлять генерацией результирующего документа XML с помощью класса XmlSerializer, необходимо декорировать типы любым количеством дополнительных атрибутов из пространства имен System.Xml.Serialization. Ниже документированы некоторые (но не все) атрибуты, которые влияют на кодирование данных XML в потоке:

[XmlAttribute]

Поле или свойство будет сериализовано как атрибут XML (а не как подэлемент)

[XmlElement]

Поле или свойство будет сериализовано как элемент XML с указанным именем

[XmlEnum]

Этот атрибут предоставляет имя элемента, являющееся членом перечисления

[XmlRoot]

Этот атрибут управляет тем, как будет сконструирован корневой элемент (пространство имен и название элемента)

[XmlText]

Свойство или поле должно быть сериализовано как текст XML (т.е. содержимое, находящееся между начальным и конечным дескрипторами корневого элемента)

[XmlType]

Этот атрибут предоставляет имя и пространство имен типа XML

Если необходимо указать специальное пространство имен XML, которое квалифицирует JamesBondCar и закодирует значения canFly и canSubmerge в виде атрибутов XML, модифицируем определение класса JamesBondCar следующим образом:

[XmlRoot(Namespace="http://professorweb.ru")]
public class JamesBondClass : Car
{
    [XmlAttribute]
    public bool canFly;

    [XmlAttribute]
    public bool canSubmerge;
}

Естественно, для управления генерацией результирующего XML-документа с помощью XmlSerializer может использоваться и множество других атрибутов. За подробной информацией обращайтесь к описанию пространства имен System.Xml.Serialization в документации .NET Framework 4.0 SDK.

Пройди тесты
Лучший чат для C# программистов