Сериализация, десериализация объекта в xml C#.

Xml является достаточно распространенным форматом.

Его можно встретить в конфигурационных файлах программ. В качестве формата передачи

данных(например выгрузка документа из бухгалтерских программ).

Или встретить в старых SOAP сервисах.

К основным недостаткам xml стоит отнести его громоздкость и большой объем символов разметки. Тут он проигрывает json.

 

Часто возникает необходимость создать файл с нуля.  А заполнять его руками слишком долго.

На форумах можно встретить два подхода – сборка документа руками из Node, в виде 50 строк.

И прямое преобразование объекта в файл – обычно не более 4х строк.

В данной статье рассмотрим краткий вариант, с использованием готовых инструментов .Net

Напомним – процесс преобразования объекта в xml называется сериализация. А процесс преобразования файла в объект – десериализаци.

 

Напишем пример сериализации объекта на .Net.

На основе примера создадим консольное приложение.

Будем сереализировать объект содержащий информацию о продукте в xml.

В проект добавим класс Product.

/// <summary>
/// Продукт
/// </summary>
public class Product
{
	/// <summary>
	/// Название продукта.
	/// </summary>
	public string Name { get; set; }

	/// <summary>
	/// Цвет продукта.
	/// </summary>
	public string Color { get; set; }

	/// <summary>
	/// Стоимость.
	/// </summary>
	public decimal Amount { get; set; }
}

Создадим и заполним объект данными.

static void Main(string[] args)
{
	Console.WriteLine("Serialize Example");

	Product fruit = new Product()
	{
		Name = "Big orange",
		Color = "Orange and green",
		Amount = 10
	};

	Console.ReadKey();
}

Добавим два метода сериализации объекта и используем их:

using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace Demo
{
	internal class Program
	{
		static void Main(string[] args)
		{
			Console.WriteLine("Serialize Example");

			Product fruit = new Product()
			{
				Name = "Big orange",
				Color = "Orange and green",
				Amount = 10
			};

			//Сериализуем объект в строку и выведем результат в окно консоли.
			string xml = SerializeToString(fruit);
			Console.WriteLine(xml);

			//Сериализуем объект в файл fruit.xml.
			SerializeToFile(fruit, "fruit.xml");

			Console.ReadKey();
		}

		/// <summary>
		/// Сериализует объект в строку.
		/// </summary>
		/// <param name="data"></param>
		/// <returns></returns>
		private static string SerializeToString(object data)
		{
			using (MemoryStream memoryStream = new MemoryStream())
			using (XmlTextWriter writer = new XmlTextWriter(memoryStream, new UTF8Encoding(false)))
			{
				writer.Formatting = Formatting.Indented;
				XmlSerializer xmlSerializer = new XmlSerializer(data.GetType());
				xmlSerializer.Serialize(writer, data);
				return Encoding.UTF8.GetString(memoryStream.ToArray());
			}
		}

		/// <summary>
		/// Сериализует объект в файл.
		/// </summary>
		/// <param name="data"></param>
		/// <param name="path"></param>
		private static void SerializeToFile(object data, string path)
		{
			using (StreamWriter writer = new StreamWriter(path))
			{
				var serializer = new XmlSerializer(data.GetType());
				serializer.Serialize(writer, data);
				writer.Flush();
			}
		}
	}
}

Если не находит XmlTextWriter в начало программы необходимо добавить using System.Xml. 

При подчеркивании красным Formatting, добавить в блок using строку using Formatting = System.Xml.Formatting.

После запуска программы в консоль выведется серилизированный объект:

А в папке с проектом будет создан файл:

 

Теперь создадим методы для обратного преобразования объектов - десериализации.

/// <summary>
///  Десериализует строку в объект.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="text"></param>
/// <returns></returns>
private static T DeserializeFromString<T>(string text)
{
	using (StringReader stringReader = new StringReader(text))
	{
		XmlTextReader xmlReader = new XmlTextReader(stringReader);
		XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
		return (T)xmlSerializer.Deserialize(xmlReader);
	}
}

/// <summary>
///Десериализация файла в объект.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="path"></param>
/// <returns></returns>
private static T DeserializeFromFile<T>(string path)
{
	using (var stream = File.OpenRead(path))
	{
		var serializer = new XmlSerializer(typeof(T));
		return (T)serializer.Deserialize(stream);
	}
}

И изменим метод Main.

	static void Main(string[] args)
	{
		Console.WriteLine("Serialize Example");

		Product fruit = new Product()
		{
			Name = "Big orange",
			Color = "Orange and green",
			Amount = 10
		};

		//Сериализуем объект в строку и выведем результат в окно консоли.
		string xml = SerializeToString(fruit);
		Console.WriteLine(xml);

		//Сериализуем объект в файл fruit.xml.
		string fileName = "fruit.xml";
		SerializeToFile(fruit, "fruit.xml");

		//Десериализация строки в объект.
		Product resultFromString = DeserializeFromString<Product>(xml);
		Console.WriteLine(resultFromString.Name); //Напечатаем название.

		//Десериализация файла в объект.
		Product resultFromFile = DeserializeFromFile<Product>(fileName);
		Console.WriteLine(resultFromFile.Name); //Напечатаем название.

		Console.ReadKey();
	}

Теперь программа производит сериализацию с кодировкой utf8, в строку и файл.

Выполняет десериализацию из файла. Название продукта выводиться в окно консоли.

Можно убрать <?xml version="1.0" encoding="utf-8"?> добавив настройки XmlWriterSettings. Или убрать xmlns из xml (пространство имен) задав пустое, используя
XmlSerializerNamespaces. 

Полный пример нового метода убирающего декларацию  <?xml version и пространство имен.

private static string SerializeToString(object data)
       {
           XmlWriterSettings settings = new XmlWriterSettings();
           settings.OmitXmlDeclaration = true; //Убрать декларацию <?xml version="1.0" encoding="utf-8"?>.
           settings.Indent = true; //Перенос на новую строку. Красивое форматирование.
           using (MemoryStream memoryStream = new MemoryStream())
           using (XmlWriter writer = XmlWriter.Create(memoryStream, settings))
           {
               XmlSerializer xmlSerializer = new XmlSerializer(data.GetType());
             
               var emptyNameSpace = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty }); //Убрать xmlns атрибут.
               xmlSerializer.Serialize(writer, data, emptyNameSpace);
               return Encoding.UTF8.GetString(memoryStream.ToArray());
           }
       }

Данный код можно использовать при создании конфигурационных файлов в формате xml. Это позволит очень быстро создать файл.

Исходники можно найти тут