‹SOAP-ENV:Envelope xmlns:xsi="…"›
‹SOAP-ENV:Body›
‹a1:JamesBondCar id="ref-1" xmlns:a1="…"›
‹canFly›true‹/canFly›
‹canSubmerge›false‹/canSubmerge›
‹theRadio href="#ref-3"/›
‹isHatchBack›false‹/isHatchBack›
‹/a1:JamesBondCar›
‹a1:Radio id="ref-3" xmlns:a1="…"›
‹hasTweeters›true‹/hasTweeters›
‹hasSubWoofers›false‹/hasSubWoofers›
‹stationPresets href="ref-4"/›
‹/a1:Radio›
‹SOAP-ENC:Array id="ref-4" SOAP-ENC:arrayType="xsd:dooble[3]"›
‹item›89.3‹/item›
‹item›105.1‹/item›
‹item›97.1‹/item›
‹/SOAP-ENC:Array›
‹/SOAP-ENV:Body›
‹/SOAP-ENV:Envelope›
Сериализация объектов с помощью XmlSerializer
Вдобавок к SOAP и двоичному формату, компоновочный блок System.Xml.dll предлагает третий формат, обеспечиваемый типом System.Xml.Serialization. XmlSerializer который может использоваться для сохранения состояния данного объекта в виде "чистого" XML в противоположность данным XML, упакованным в сообщении SOAP. Работа с этим типом немного отличается от работы с типами SoapFormatter и BinaryFormatter. Рассмотрим следующий программный код.
using Sуstem.Xml.Serialization;
…
static void Main(string[] args) {
…
// Сохранение объекта в файл CarData.xml в формате XML.
XmlSerializer xmlFormat = new XmlSerializer(typeof(JamesBondCar), new Type[] { typeof(Radio), typeof(Car) });
fStream = new FileStream("CarData.xml", FileMode.Create, FileAccess.Write, FileShare.None);
xmlFormat.Serialize(fStream, jbc);
fStream.Close();
…
}
Здесь главным отличием является то, что тип XmlSerializer требует указания информации о типе соответствующего элемента объектного графа. Обратите внимание на то, что первый аргумент конструктора XmlSerializer определяет корневой элемент XML-файла, а второй аргумент является массивом типов System.Type, содержащих метаданные подчиненных элементов. Если заглянуть в сгенерированный файл CarData.xml, вы увидите следующий XML-код (здесь он приводится в сокращенном виде).
‹?xml version="1.0" encoding="utf-8"?›
‹JamesBondCar xmlns:xsi="…"›
‹theRadio›
‹hasTweeters›true‹/hasTweeters›
‹hasSubWoofers›false‹/hasSubwoofers›
‹stationPresets›
‹double›89.3‹/double›
‹double›105.1‹/double›
‹double›97.1‹/double›
‹/stationPresets›
‹/theRadio›
‹isHatchBack›false‹/isHatchBack›
‹canFly›true‹/canFly›
‹canSubmerge›false‹/canSubmerge›
‹/JamesBondCar›
Замечание.Для XmlSerializer требуется, чтобы все типы в объектном графе, предназначенные для сериализации, поддерживали конструктор, заданный по умолчанию (так что не забудьте добавить его, если вы определили пользовательские конструкторы). Если это условие не будет выполнено, в среде выполнения будет сгенерировано исключение InvalidOperationException.
Контроль генерируемых XML-данных
Если у вас есть опыт использования XML-технологий, вы должны хорошо знать о том, что в документе XML очень важно гарантировать соответствие элементов набору правил, обеспечивающих "допустимость" данных. Следует понимать, что "допустимость" XML-документа не связана напрямую с синтаксической правильностью его XML-элементов (например, с требованием о том, что все открываемые элементы должны иметь закрывающие их дескрипторы). Скорее, допустимость документов связана с правилами форматирования (например, поле X должно быть атрибутом и не вложенным элементом), которые обычно задаются XML-схемой или DTD-файлом (файл определения типа документа),
По умолчанию все поля данных типа [Serializable] форматируются, как элементы, а не как XML-атрибуты. Для контроля того, как XmlSerializer компонует генерируемый XML-документ, следует указать для типов [Serializable] дополнительные атрибуты из пространства имен System.Xml.Serialization. В табл. 17.1 представлены некоторые из атрибутов, влияющих на кодирование XML-данных, передаваемых в поток.
Таблица 17.1.Атрибуты пространства имен System.Xml.Serialization, связанные с сериализацией объектов
Атрибут |
Описание |
XmlAttributeAttribute |
Член будет сохранен в виде XML-атрибута |
XmlElementAttribute |
Поле или свойство будут сохранены в виде XML-элемента |
XmlEnumAttribute |
Имя элемента перечня |
XmlRootAttribute |
Атрибут, контролирующий формат корневого элемента (пространство имен и имя элемента) |
XmlTextAttribute |
Свойство или поле должно сохраняться в виде XML-текста |
XmlTypeAtttribute |
Имя и пространство имен XML-типа |
Для примера давайте сначала выясним, как поля данных JamesBondCar сохраняются в XML-документе в настоящий момент.
‹?xml version="1.0" encodings="utf-8"?›
‹JamesBondCar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd=http://www.w3.org/2001/XMLSchema›
Читать дальше