private void WriteXmlEnumerable(XmlWriter writer, IHierarchy <object> current, bool skipStartElement = false) { Type currentType = current.InstanceType; Type[] genericParameters = currentType.GetGenericArguments(); if (genericParameters.Length == 0) { genericParameters = null; } if (TypeUtility.IsEnumerable(currentType) && currentType != typeof(string)) { bool isDictionary = TypeUtility.IsDictionary(currentType); IEnumerable enumerable = current.Instance as IEnumerable; if (enumerable != null) { var list = enumerable.Cast <object>().ToList(); if (!skipStartElement && !current.HasChildren && list.Count > 0) { XmlQualifiedEntity qualifiedEntity = null; if (!current.InstanceType.HasAttributes(typeof(XmlRootAttribute)) && current.MemberReference == null) { qualifiedEntity = new XmlQualifiedEntity(StringConverter.FromType(current.InstanceType, false, true).SanitizeElementName()); } qualifiedEntity = current.LookupXmlStartElement(qualifiedEntity); writer.WriteStartElement(qualifiedEntity.Prefix, qualifiedEntity.LocalName, qualifiedEntity.Namespace); } IEnumerator enumerator = list.GetEnumerator(); IHierarchy <object> enumeratorNode = new Hierarchy <object>(); enumeratorNode.Add(enumerator); while (enumerator.MoveNext()) { object value = enumerator.Current; if (value == null) { continue; } writer.WriteStartElement(EnumerableElementName); Type valueType = value.GetType(); if (isDictionary) { PropertyInfo keyProperty = valueType.GetProperty("Key"); PropertyInfo valueProperty = valueType.GetProperty("Value"); object keyValue = keyProperty.GetValue(value, null) ?? "null"; object valueValue = valueProperty.GetValue(value, null) ?? "null"; var kvpWrapper = DynamicXmlSerializable.Create(new[] { keyValue, valueValue }, (xmlWriter, o) => { var k = o[0]; var v = ReflectionUtility.GetObjectHierarchy(o[1], options => options.MaxDepth = 0); v.Data.Add("enumerableCaller", true); writer.WriteAttributeString("key", k.ToString()); XmlQualifiedEntity qualifiedEntity = null; if (genericParameters != null && genericParameters.Length > 0) { qualifiedEntity = new XmlQualifiedEntity(StringConverter.FromType(genericParameters.Last(), false, true).SanitizeElementName()); } qualifiedEntity = v.LookupXmlStartElement(qualifiedEntity); writer.WriteStartElement(qualifiedEntity.Prefix, qualifiedEntity.LocalName, qualifiedEntity.Namespace); WriteXmlNodes(writer, v); writer.WriteEndElement(); }); WriteXmlNodes(writer, ReflectionUtility.GetObjectHierarchy(kvpWrapper, options => options.MaxDepth = 0)); } else { IHierarchy <object> itemNode = ReflectionUtility.GetObjectHierarchy(value, options => options.MaxDepth = 0); itemNode.Data.Add("enumerableCaller", true); XmlQualifiedEntity qualifiedEntity = null; if (genericParameters != null && genericParameters.Length > 0) { qualifiedEntity = new XmlQualifiedEntity(StringConverter.ToDelimitedString(genericParameters, "And", StringConverter.FromType)); } qualifiedEntity = itemNode.LookupXmlStartElement(qualifiedEntity); writer.WriteStartElement(qualifiedEntity.Prefix, qualifiedEntity.LocalName, qualifiedEntity.Namespace); WriteXmlNodes(writer, itemNode); writer.WriteEndElement(); } writer.WriteEndElement(); } if (!skipStartElement && !current.HasChildren && list.Count > 0) { writer.WriteEndElement(); } } } }