Маппинг 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) Использование спец. библиотек, к примеру OXMObject Xml Mapping

Как пишут создатели этого продукта:

  • Полный контроль над генерацией XML
  • POCO подход, без атрибутов  и тд (нет необходимости изменять ваши сущности)
  • Удобный DSL дл объявления маппинга
  • Строгая типизация
  • Отсутствие рефлексии

Данный подход аналогичен ORM (объектно-реляционный маппинг). DSL для объявления маппинга создан на по аналогии с FluentNHibernate
http://wiki.oxm.googlecode.com/hg/orm_oxm.png

Пример использования:

Класс 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);
}
Библиотеки также поддерживает конструкторы объектов не по-умолчанию (с параметрами), коллекции, ссылки на объекты и многое другое.
Сайт проекта: http://code.google.com/p/oxm/
Один комментарий
  1. Дмитрий написал:

    А не легче подогнать все под дефолтный сериализатор просто сделав мэппинг в MapForce?

Оставить комментарий