Маппинг XML-данных и C#-объектов
Задача: осуществить маппинг XML-данных и C#-объектов для наиболее простого преобразования в обе стороны, с учетом стоимости поддержки выбранного решения
1) Наиболее простой способ – генерация c#-классов на основе существующей XSD-схемы с помощью утилиты xsd.exe
Подробное описание утилиты: http://msdn.microsoft.com/en-us/library/x6c1kb0s
Преобразования XML->наши классы и обратно выполняем с помощью сериализации:
public static string SerializeToXMLString(object ObjectToSerialize)
{
MemoryStream mem = new MemoryStream();
System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(ObjectToSerialize.GetType());
ser.Serialize(mem,ObjectToSerialize);
ASCIIEncoding ascii = new ASCIIEncoding();
return ascii.GetString(mem.ToArray());
}
public static object DeSerializeFromXMLString(System.Type TypeToDeserialize, string xmlString)
{
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(xmlString);
MemoryStream mem = new MemoryStream(bytes);
System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(TypeToDeserialize);
return ser.Deserialize(mem);
}
Сериализацию можно обойти с помощью LINQ To XML – предоставляет удобный механизм для разбора XML-данных.
Варианты разбора XML классическим способом рассматривать не будем.
2) Использование спец. библиотек, к примеру OXM - Object Xml Mapping
Как пишут создатели этого продукта:
- Полный контроль над генерацией XML
- POCO подход, без атрибутов и тд (нет необходимости изменять ваши сущности)
- Удобный DSL дл объявления маппинга
- Строгая типизация
- Отсутствие рефлексии
Данный подход аналогичен ORM (объектно-реляционный маппинг). DSL для объявления маппинга создан на по аналогии с FluentNHibernate

Пример использования:
Класс Person:
public class Person
{ //
public string Name { get; set; } // 12
public int Age { get; set; } //
}
Маппинг класса Person:
public class PersonMap : RoolElementMap
{
Person person = new Person();
public PersonMap()
{
Map(o => o.Name).ToAttribute("name", true)
.Set(v => person.Name = v)
.Converter(new StringConverter());
Map(o => o.Age).ToSimpleElement("Age", true)
.Set(v => person.Age = v)
.Converter(new Int32Converter());
}
protected override Person Return()
{
return person;
}
public override XName Name
{
get { return "Person"; }
}
}
Пример преобразования:
[Test]
public void PersonMap()
{
var person = new Person() { Name = "John Smith", Age = 12 };
var map = new PersonMap();
var doc = new XDocument();
using (var writer = doc.CreateWriter())
{
map.WriteXml(writer, person);
}
Person person2;
using (var reader = doc.CreateReader())
{
person2 = map.ReadXml(reader);
}
Assert.AreEqual(person.Name, person2.Name);
Assert.AreEqual(person.Age, person2.Age);
}

11 августа, 2010 в 15:07
А не легче подогнать все под дефолтный сериализатор просто сделав мэппинг в MapForce?