XmlSerializer
21C# и .NET --- Многопоточность и файлы --- XmlSerializer
В дополнение к двоичному форматеру и форматеру 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.