Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

ExpandoObject: Serialization OOP and Processing XML Files without Heads Taken

0.00/5 (No votes)
19 Feb 2016 1  
It is often requested by the customer to import a data file in XML format. It is therefore easier to work in object mode, however, the XML transformation into a pure object might take time to be developed. ExpandoObject provides an answer to this problem ...

What is ExpandoObject?

The ExpandoObject class is an implementation of dynamic object concept that enables the acquisition, definition and calling of members. If you want to define types that have their own semantic dynamic distribution, use DynamicObject class. If you want to define how dynamic objects participate in the interoperability protocol and manage caching of fast dynamic distribution DLR, create your own implementation of the interface IDynamicMetaObjectProvider.

  • Spacename: System.Dynamic
  • Assembly: System.Core (dans System.Core.dll)
  • Object hierarchy:
  • System.Object
  • System.Dynamic.ExpandoObject

Functioning Context

It is often requested by the customer to import a data file in XML format. It is therefore easier to work in object mode, however, the XML transformation into a pure object might be time for development. ExpandoObject provides an answer to this problem by providing a serialization mechanism without cumbersome and complex code implementation.

How It Works?

Helper

It is the helper's responsibility to read the XML file and return a collection of objects of type ExpandoObject.

The XML File

The XML file contains the object collection to be deserialised.

ImportProcessor

This class is responsible for processing and mapping of ExpandoObject entity objects (POCO).

Do It Yourself (Visual Studio 2015 / C# 4.5)

  1. Open the solution created in my previous article on Unity: Unity Microsoft 4 / Genericity of the data access layer
  2. In my library STPVideoPlayer.DataLayer, add a new class named helper ExpandoHelper, this class has the responsibility to read the XML file and to call a processing class to transform data

    Note here, the use of the object PluralizationService which allows using the English culture pluralize names or single out.

    var pluralizationService = PluralizationService.CreateService(new CultureInfo("en-US"));
    var item = new ExpandoObject();
    
  3. To read a file, we will use the method ExpandoHelper.ReadDocument(xmlFile)

ExpandoHelper : [C#]

public static class ExpandoHelper
{
    public static dynamic ReadDocument(string path)
    {
        XDocument xDoc = null;

        if (Path.IsPathRooted(path) == false)
        {
            path = System.Web.HttpContext.Current.Server.MapPath(path);
        }

        xDoc = XDocument.Load(path);
        dynamic root = new ExpandoObject();

        Parse(root, xDoc.Elements().First());

        return root;
    }

    public static void Parse(dynamic parent, XElement node)
    {
        var pluralizationService = PluralizationService.CreateService(new CultureInfo("en-US"));
        var item = new ExpandoObject();

        string name = pluralizationService.Singularize(node.Name.LocalName);

        name = name.EndsWith("s") ? name.TrimEnd('s') : name;

        if (node.Elements(XName.Get(name)).Count() > 0)
        {
            var list = new List<dynamic>();

            foreach (XElement child in node.Elements(XName.Get(name)))
            {
                Parse(list, child);
            }

            AddProperty(parent, node.Name.ToString(), list);
        }
        else
        {
            foreach (var attribute in node.Attributes())
            {
                AddProperty(item, attribute.Name.ToString(), attribute.Value);
            }

            if (node.HasElements)
            {
                foreach (var element in node.Elements())
                {
                    var list = new List<dynamic>();

                    string nameItem = pluralizationService.Singularize(element.Name.ToString());

                    if (element.Elements(nameItem).Count() > 0)
                    {
                        foreach (var ch in element.Elements(nameItem))
                        {
                            Parse(list, ch);
                        }
                    }
                    else
                    {
                        Parse(list, element);
                    }

                    AddProperty(item, element.Name.ToString(), list);
                }
            }

            AddProperty(parent, name, item);
        }
    }

    private static void AddProperty(dynamic parent, string name, object value)
    {
        if (parent is List<dynamic>)
        {
            (parent as List<dynamic>).Add(value);
        }
        else
        {
            (parent as IDictionary<string, object>)[name] = value;
        }
    }
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here