Thursday, January 23, 2014

ExpandoObject to Xml

В этой статье поговорим о том, как динамические возможности языка C# позволяют упростить реализацию некоторых вещей. Рассмотрим, как ExpandoObject позволяет упростить работу с XML. В .NET Framework 4/4.5 для работы с xml доступно несколько способов чтения и записи в xml-файл:
  • XmlReader/XmlWriter;
  • XmlDocument;
  • XDocument.
Первый вариант - самый быстрый, так как позволяет писать и читать с xml документа на самом низком уровне. Второй вариант основан на xml dom и позволяет зачитывать документ в память и изменять его в ней. Третий вариант построен на модели linq, которая называется LINQ to Xml. (Пример для реализации взят с блога).
class Program
{
    static void Main(string[] args)
    {
        var contactXML =
            new XElement("Contact",
                new XElement("Name", "Patrick Hines"),
                new XElement("Phone", "206-555-0144"),
                new XElement("Address",
                    new XElement("Street1", "123 Main St"),
                    new XElement("City", "Mercer Island"),
                    new XElement("State", "WA"),
                    new XElement("Postal", "68042")
                )
            );

        Console.WriteLine(contactXML.ToString());
        Console.ReadLine();
    }
}
В результате на экране мы увидим результат:
Было бы очень удобно, если бы мы могли создавать объекты на лету, а затем так же легко их перевоплотить в xml. Посмотрите, как удобен синтаксис dynamic/ExpandoObject, чтобы вывести необходимые нам данные:
dynamic contact = new ExpandoObject();
contact.Name = "Patrick Hines";
contact.Phone = "206-555-0144";
contact.Address = new ExpandoObject();
contact.Address.Street = "123 Main St";
contact.Address.City = "Mercer Island";
contact.Address.State = "WA";
contact.Address.Postal = "68402";
У нас получился очень компактный код, который было бы неплохо сразу превратить в xml, json или какой-то другой формат. К счастью, для этого есть готовые решения, и одно из них мы сегодня рассмотрим. Для примера использовался класс ElasticObject. Вы можете скачать библиотеку для использования данного класса с помощью Manage Nuget Packages, используя слово для поиска ElasticObject.

Либо можно воспользоваться Package Manager Console.
PM> Install-Package AmazedSaint.ElasticObject
После этого станет доступно много возможностей для конвертации динамического объекта в xml или json.
static void Main(string[] args)
{
    dynamic contact = new ElasticObject("Contact");
    contact.Name = "Patrick Hines";
    contact.Phone = "206-555-0144";
    contact.Address.Street = "123 Main St";
    contact.Address.City = "Mercer Island";
    contact.Address.State = "WA";
    contact.Address.Postal = "68402";

    XElement element = contact > FormatType.Xml;
    Console.WriteLine(element.ToString());
    Console.ReadLine();
}
Результат вывода на экран:
С помощью оператора ‘>’ мы указываем, в какой формат мы хотим конвертировать только что созданный объект. Также интересным свойством данного класса есть возможность конвертации с XElement обратно в ElasticObject.
static void Main(string[] args)
{
    dynamic contact = new ElasticObject("Contact");
    contact.Name = "Patrick Hines";
    contact.Phone = "206-555-0144";
    contact.Address.Street = "123 Main St";
    contact.Address.City = "Mercer Island";
    contact.Address.State = "WA";
    contact.Address.Postal = "68402";

    XElement element = contact > FormatType.Xml;
    Console.WriteLine(element.ToString());

    dynamic elasticObject = element.ToElastic();
    elasticObject.Age = 18;

    XElement cloneElement = elasticObject > FormatType.Xml;
    Console.WriteLine(cloneElement.ToString());
    Console.ReadLine();
}
В приведенном примере мы делаем превращение ElasticObject->XElement, затем делаем обратное превращение с XElement-> ElasticObject, добавляем новый элемент Age и сохраняем обратно в xml. Для такой сложной конвертации нам понадобилось прописать всего три строчки кода. Создать коллекцию для конвертации ее в xml достаточно просто.
static void Main(string[] args)
{
    dynamic contacts = new ElasticObject("Contacts");
    var contact1 = contacts.Contract();
    contact1.Name = "Patrick Hines";
    contact1 <<= "Test content for first contact";
    contact1.Phone = "206-555-0144";

    var contact2 = contacts.Contract();
    contact2.Name = "Ellen Adams";
    contact2.Phone = "206-555-0155";
    XElement element = contacts > FormatType.Xml;
    Console.WriteLine(element.ToString());

    Console.ReadLine();
}
По моему мнению, данный код не настолько интуитивно понятен, как код, описанный выше. Но он также довольно прост для понимания и использования. Посмотрим, что у нас получилось после запуска примера:
Чтобы создать динамический элемент для xml, мы можем воспользоваться оператором ‘<<’. Для атрибутов добавление можно производить с помощью оператора ‘<’.
class Program
{
    static void Main(string[] args)
    {
        dynamic tests = new ElasticObject("Tests");
        for (int i = 0; i < 5; i++)
        {
            dynamic newItem = tests << "Item";
            dynamic attribute = newItem < "Attribute" + i;
            attribute <<= "somevalue";
            newItem <<= "Item" + i;
        }

        XElement element = tests > FormatType.Xml;
        Console.WriteLine(element.ToString());
        Console.ReadLine();
    }
}
Результат выполнения приведен ниже.


Итоги
В приведенной статье мы рассмотрели создание динамических объектов и сохранение их в xml. Надеюсь, что статья окажется полезной для Вас, и Вы сможете применять динамические возможности языка C# в своих проектах.

Список литературы


No comments:

Post a Comment