Exemplo n.º 1
0
        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();
                    }
                }
            }
        }