using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Xml; using System.Xml.Linq; /// /// Extension methods for the dynamic object. /// public static class DynamicHelper { /// /// Defines the simple types that is directly writeable to XML. /// private static readonly Type[] _writeTypes = new[] { typeof(string), typeof(DateTime), typeof(Enum), typeof(decimal), typeof(Guid) }; /// /// Determines whether [is simple type] [the specified type]. /// /// The type to check. /// /// true if [is simple type] [the specified type]; otherwise, false. /// public static bool IsSimpleType(this Type type) { return type.IsPrimitive || _writeTypes.Contains(type); } /// /// Converts the specified dynamic object to XML. /// /// The dynamic object. /// Returns an Xml representation of the dynamic object. public static XElement ConvertToXml(dynamic dynamicObject) { return ConvertToXml(dynamicObject, null); } /// /// Converts the specified dynamic object to XML. /// /// The dynamic object. /// /// The element name. /// Returns an Xml representation of the dynamic object. public static XElement ConvertToXml(dynamic dynamicObject, string element) { if (String.IsNullOrWhiteSpace(element)) { element = "object"; } element = XmlConvert.EncodeName(element); var ret = new XElement(element); Dictionary members = new Dictionary(dynamicObject); var elements = from prop in members let name = XmlConvert.EncodeName(prop.Key) let val = prop.Value.GetType().IsArray ? "array" : prop.Value let value = prop.Value.GetType().IsArray ? GetArrayElement(prop.Key, (Array)prop.Value) : (prop.Value.GetType().IsSimpleType() ? new XElement(name, val) : val.ToXml(name)) where value != null select value; ret.Add(elements); return ret; } /// /// Generates an XML string from the dynamic object. /// /// The dynamic object. /// Returns an XML string. public static string ToXmlString(dynamic dynamicObject) { XElement xml = DynamicHelper.ConvertToXml(dynamicObject); return xml.ToString(); } /// /// Converts an anonymous type to an XElement. /// /// The input. /// Returns the object as it's XML representation in an XElement. public static XElement ToXml(this object input) { return input.ToXml(null); } /// /// Converts an anonymous type to an XElement. /// /// The input. /// The element name. /// Returns the object as it's XML representation in an XElement. public static XElement ToXml(this object input, string element) { if (input == null) { return null; } if (String.IsNullOrWhiteSpace(element)) { element = "object"; } element = XmlConvert.EncodeName(element); var ret = new XElement(element); if (input != null) { var type = input.GetType(); var props = type.GetProperties(); var elements = from prop in props let name = XmlConvert.EncodeName(prop.Name) let val = prop.PropertyType.IsArray ? "array" : prop.GetValue(input, null) let value = prop.PropertyType.IsArray ? GetArrayElement(prop, (Array)prop.GetValue(input, null)) : (prop.PropertyType.IsSimpleType() ? new XElement(name, val) : val.ToXml(name)) where value != null select value; ret.Add(elements); } return ret; } /// /// Parses the specified XML string to a dynamic. /// /// The XML string. /// A dynamic object. public static dynamic ParseDynamic(this string xmlString) { throw new NotImplementedException(); } /// /// Gets the array element. /// /// The property info. /// The input object. /// Returns an XElement with the array collection as child elements. private static XElement GetArrayElement(PropertyInfo info, Array input) { return GetArrayElement(info.Name, input); } /// /// Gets the array element. /// /// The property name. /// The input object. /// Returns an XElement with the array collection as child elements. private static XElement GetArrayElement(string propertyName, Array input) { var name = XmlConvert.EncodeName(propertyName); XElement rootElement = new XElement(name); var arrayCount = input.GetLength(0); for (int i = 0; i < arrayCount; i++) { var val = input.GetValue(i); XElement childElement = val.GetType().IsSimpleType() ? new XElement(name + "Child", val) : val.ToXml(); rootElement.Add(childElement); } return rootElement; } }