Страница 1 из 5 Xml широко используется в .Net приложениях, и .Net framework предоставляет богатые возможности по работе с Xml. Среди них: поддержка Xml DOM (System.Xml.XmlDocument), последовательное чтение - запись Xml, поддержка xPath и xQuery, поддержка XSLT, богатые возможности DataSet по работе с Xml и, наконец, Xml сериализация.
Xml сериализация позволяет представлять Xml в виде иерархии классов, и наоборот, данные классов представлять в виде Xml. Когда стоит использовать Xml сериализацию? Мое мнение таково. Во всех случаях, когда нам заранее известна структура Xml, с которым предстоит работать, следует использовать Xml сериализацию. Как работает Xml сериализация При Xml сериализации, сериализуются все открытые поля и свойства класса. Кроме того, открытые свойства должны иметь аксессоры get и set, а сам класс должен иметь конструктор по умолчанию без параметров. Рассмотрим класс: public class DataClass { public DataClass(){} public string ID = Guid.NewGuid().ToString(); public string Name = "Just Name"; public Decimal Count = 10; public DateTime Date = DateTime.Now; }
Его мы будем использовать во всех дальнейших примерах сериализации и десериализации. Для сериализации нам надо создать экземпляр класса XmlSerializer, предав в качестве параметра конструктора тип сериализуемого класса. Следующий код демонстрирует сериализацию объекта нашего класса DataClass: DataClass obj = new DataClass();
XmlSerializer sr = new XmlSerializer(obj.GetType());
StringBuilder sb = new StringBuilder(); StringWriter w = new StringWriter(sb, System.Globalization.CultureInfo.InvariantCulture);
sr.Serialize(w,obj);
string xml = sb.ToString(); Console.WriteLine(xml);
В результате получаем вот такой Xml: <?xml version="1.0" encoding="utf-8"?> <DataClass xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"> <ID>34332413-e70f-44f7-b35c-b34c47812dbc</ID> <Name>Just Name</Name> <Count>10</Count> <Date>2006-10-30T12:35:20.3110319+03:00</Date> </DataClass>
Для того, чтобы получить из этого Xml экземпляр класса DataClass (десериализовать), служит следующий код: StringReader reader = new StringReader(xml);
XmlSerializer dsr = new XmlSerializer(typeof(DataClass));
DataClass clone = (DataClass)dsr.Deserialize(reader);
Управлять, тем как свойства и поля объекта отображаются на элементы Xml, можно при помощи атрибутов, которые содержатся в пространстве имен System.Xml.Serialization. Допустим, мы хотим, чтобы в результирующем Xml корневой элемент назывался <Data>, поля “ID”, “Name” сериализовались Xml атрибутами, поле “Count” соответствовало Xml элементу <Reserved>, а поле “Date”, вообще не попадало в результирующий Xml. Для этого расставим соответствующие атрибуты: [XmlRoot("Data")] public class DataClass { public DataClass(){}
[XmlAttribute] public string ID = Guid.NewGuid().ToString();
[XmlAttribute] public string Name = "Just Name";
[XmlElement("Reserved")] public Decimal Count = 10;
[XmlIgnore] public DateTime Date = DateTime.Now; }
Результирующий Xml теперь выглядит так: <?xml version="1.0" encoding="utf-8"?> <Data xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" ID="cc340d5e-4c80-4fe5-9c3d-e49f64e26b22" Name="Just Name"> <Reserved>10</Reserved> </Data>
Как видно из представленного кода, использовать Xml сериализацию не сложно. Но все же попробуем облегчить себе жизнь. Для этого вынесем код, ответственный за сериализацию в отдельный класс утилиту: public class XmlUtility { /// <summary>
/// Сериализует объект в строку XML
/// </summary>
public static string Obj2XmlStr(object obj, string nameSpace) { if (obj == null) return string.Empty; XmlSerializer sr = new XmlSerializer(type); StringBuilder sb = new StringBuilder(); StringWriter w = new StringWriter(sb, System.Globalization.CultureInfo.InvariantCulture); sr.Serialize( w, obj, new XmlSerializerNamespaces( new XmlQualifiedName[] { new XmlQualifiedName("", nameSpace) } )); return sb.ToString(); }
/// <summary>
/// Сериализует объект в строку XML
/// </summary>
public static string Obj2XmlStr(object obj) { if (obj == null) return string.Empty; XmlSerializer sr = new XmlSerializer(obj.GetType()); StringBuilder sb = new StringBuilder(); StringWriter w = new StringWriter(sb, System.Globalization.CultureInfo.InvariantCulture); sr.Serialize( w, obj, new XmlSerializerNamespaces( new XmlQualifiedName[] { new XmlQualifiedName(string.Empty) } ) ); return sb.ToString(); }
/// <summary>
/// Десериализует строку XML в объект заданного типа
/// </summary>
/// <param name="xml"></param>
/// <param name="type"></param>
/// <returns></returns>
public static T XmlStr2Obj<T>(string xml) { if (xml == null) return default(T); if (xml == string.Empty) return (T)Activator.CreateInstance(typeof(T));
StringReader reader = new StringReader(xml); XmlSerializer sr = new XmlSerializer(typeof(T)); return (T)sr.Deserialize(reader); } }
Назначение метода Obj2XmlStr(object obj, string nameSpace) я объясню несколько позже. Теперь наш код для сериализации и десериализации объекта сократился в несколько раз: DataClass obj = new DataClass(); string xml = XmlUtility.Obj2XmlStr(obj); Console.WriteLine(xml); DataClass clone = XmlUtility.XmlStr2Obj<DataClass>(xml); Полный код класса XmlUtility вы найдете в исходном коде, прилагаемом к статье. |