示例#1
0
        public static XmlMapper Build(object that, string rootName = null)
        {
            if (that == null)
            {
                throw new ArgumentNullException(nameof(that));
            }
            if (string.IsNullOrEmpty(rootName))
            {
                rootName = that.GetType().Name;
            }
            XmlMapper mapper = new XmlMapper();

            Build(mapper, that, rootName);
            return(mapper);
        }
示例#2
0
        private static void Build(XmlMapper mapper, object that, string rootName)
        {
            Type type = that.GetType();
            Attribute[] typeAttributes = Attribute.GetCustomAttributes(type);
            Attribute include = typeAttributes.FirstOrDefault(p => p is ClassWithIncludeAttribute);

            List<PropertyInfo> propertyInfos = new List<PropertyInfo>(type.GetProperties(BindingFlags.Public | BindingFlags.Instance));
            List<PropertyInfo> ignores = new List<PropertyInfo>();

            PropertyInfo propertyMap = null;
            Dictionary<string, string> map = new Dictionary<string, string>();
            foreach (PropertyInfo propertyInfo in propertyInfos)
            {
                if (!propertyInfo.PropertyType.IsClass && propertyInfo.PropertyType != typeof(string))
                {
                    // 2015-08-31 emiya: Not supported type
                    ignores.Add(propertyInfo);
                    continue;
                }
                object[] attributes = propertyInfo.GetCustomAttributes(true);
                if (attributes.Any(p => p is PropertyMapAttribute))
                {
                    propertyMap = propertyInfo;
                    continue;
                }
                if (attributes.Any(p => p is PropertyIgnoreAttribute))
                {
                    ignores.Add(propertyInfo);
                    continue;
                }
                if (include != null && !attributes.Any(p => p is PropertyIncludeAttribute))
                {
                    ignores.Add(propertyInfo);
                    continue;
                }

                map.Add(propertyInfo.Name, propertyInfo.Name);
            }

            if (propertyMap != null)
            {
                Dictionary<string, string> names = propertyMap.GetValue(that, null) as Dictionary<string, string>;
                if (names != null)
                {
                    propertyInfos.Remove(propertyMap);

                    Dictionary<string, string> merge = names.Concat(map).GroupBy(p => p.Key)
                        .ToDictionary(group => group.Key, group => group.First().Value);

                    map = merge;
                }
            }
            foreach (var ignore in ignores)
            {
                propertyInfos.Remove(ignore);
            }

            if (!string.IsNullOrEmpty(rootName)) mapper.StartElement(rootName);
            foreach (var propertyInfo in propertyInfos)
            {
                string localName;
                if (!map.TryGetValue(propertyInfo.Name, out localName)) continue;

                Type propertyType = propertyInfo.PropertyType;
                if (!propertyType.IsClass || propertyType == typeof(string))
                {
                    mapper.InsertElement(that, propertyInfo, localName);
                    continue;
                }

                object value = propertyInfo.GetValue(that, null);
                object[] attributes = propertyInfo.GetCustomAttributes(true);
                bool isCollection = typeof(IEnumerable).IsAssignableFrom(propertyType);
                bool withoutRoot = attributes.Any(p => p is PropertyWithoutRootAttribute);
                bool withoutNode = attributes.Any(p => p is PropertyWithoutNodeAttribute);
                if (isCollection)
                {
                    if (!withoutRoot) mapper.StartElement(localName);
                    string itemName = null;
                    if (!withoutNode)
                    {
                        PropertyItemNameAttribute propertyItem = (PropertyItemNameAttribute)attributes.FirstOrDefault(p => p is PropertyItemNameAttribute);
                        if (propertyItem == null)
                        {
                            if (propertyType.IsGenericType)
                            {
                                if (propertyType.GetGenericTypeDefinition() == typeof (List<>))
                                {
                                    itemName = propertyType.GetGenericArguments()[0].Name;
                                }
                                else
                                {
                                    throw new NotSupportedException();
                                }
                            }
                        }
                        else
                        {
                            itemName = propertyItem.ItemName;
                        }
                    }
                    foreach (object item in ((IEnumerable) value))
                    {
                        Build(mapper, item, itemName);
                    }
                    if (!withoutRoot) mapper.EndElement();
                    continue;
                }

                if (withoutNode) localName = null;
                Build(mapper, value, localName);

            }
            if (!string.IsNullOrEmpty(rootName)) mapper.EndElement();
        }
示例#3
0
 public static XmlMapper Build(object that, string rootName = null)
 {
     if (that == null)
         throw new ArgumentNullException(nameof(that));
     if (string.IsNullOrEmpty(rootName)) rootName = that.GetType().Name;
     XmlMapper mapper = new XmlMapper();
     Build(mapper, that, rootName);
     return mapper;
 }
示例#4
0
        private static void Build(XmlMapper mapper, object that, string rootName)
        {
            Type type = that.GetType();

            Attribute[] typeAttributes = Attribute.GetCustomAttributes(type);
            Attribute   include        = typeAttributes.FirstOrDefault(p => p is ClassWithIncludeAttribute);

            List <PropertyInfo> propertyInfos = new List <PropertyInfo>(type.GetProperties(BindingFlags.Public | BindingFlags.Instance));
            List <PropertyInfo> ignores       = new List <PropertyInfo>();

            PropertyInfo propertyMap        = null;
            Dictionary <string, string> map = new Dictionary <string, string>();

            foreach (PropertyInfo propertyInfo in propertyInfos)
            {
                if (!propertyInfo.PropertyType.IsClass && propertyInfo.PropertyType != typeof(string))
                {
                    // 2015-08-31 emiya: Not supported type
                    ignores.Add(propertyInfo);
                    continue;
                }
                object[] attributes = propertyInfo.GetCustomAttributes(true);
                if (attributes.Any(p => p is PropertyMapAttribute))
                {
                    propertyMap = propertyInfo;
                    continue;
                }
                if (attributes.Any(p => p is PropertyIgnoreAttribute))
                {
                    ignores.Add(propertyInfo);
                    continue;
                }
                if (include != null && !attributes.Any(p => p is PropertyIncludeAttribute))
                {
                    ignores.Add(propertyInfo);
                    continue;
                }

                map.Add(propertyInfo.Name, propertyInfo.Name);
            }

            if (propertyMap != null)
            {
                Dictionary <string, string> names = propertyMap.GetValue(that, null) as Dictionary <string, string>;
                if (names != null)
                {
                    propertyInfos.Remove(propertyMap);

                    Dictionary <string, string> merge = names.Concat(map).GroupBy(p => p.Key)
                                                        .ToDictionary(group => group.Key, group => group.First().Value);

                    map = merge;
                }
            }
            foreach (var ignore in ignores)
            {
                propertyInfos.Remove(ignore);
            }

            if (!string.IsNullOrEmpty(rootName))
            {
                mapper.StartElement(rootName);
            }
            foreach (var propertyInfo in propertyInfos)
            {
                string localName;
                if (!map.TryGetValue(propertyInfo.Name, out localName))
                {
                    continue;
                }

                Type propertyType = propertyInfo.PropertyType;
                if (!propertyType.IsClass || propertyType == typeof(string))
                {
                    mapper.InsertElement(that, propertyInfo, localName);
                    continue;
                }


                object   value        = propertyInfo.GetValue(that, null);
                object[] attributes   = propertyInfo.GetCustomAttributes(true);
                bool     isCollection = typeof(IEnumerable).IsAssignableFrom(propertyType);
                bool     withoutRoot  = attributes.Any(p => p is PropertyWithoutRootAttribute);
                bool     withoutNode  = attributes.Any(p => p is PropertyWithoutNodeAttribute);
                if (isCollection)
                {
                    if (!withoutRoot)
                    {
                        mapper.StartElement(localName);
                    }
                    string itemName = null;
                    if (!withoutNode)
                    {
                        PropertyItemNameAttribute propertyItem = (PropertyItemNameAttribute)attributes.FirstOrDefault(p => p is PropertyItemNameAttribute);
                        if (propertyItem == null)
                        {
                            if (propertyType.IsGenericType)
                            {
                                if (propertyType.GetGenericTypeDefinition() == typeof(List <>))
                                {
                                    itemName = propertyType.GetGenericArguments()[0].Name;
                                }
                                else
                                {
                                    throw new NotSupportedException();
                                }
                            }
                        }
                        else
                        {
                            itemName = propertyItem.ItemName;
                        }
                    }
                    foreach (object item in ((IEnumerable)value))
                    {
                        Build(mapper, item, itemName);
                    }
                    if (!withoutRoot)
                    {
                        mapper.EndElement();
                    }
                    continue;
                }


                if (withoutNode)
                {
                    localName = null;
                }
                Build(mapper, value, localName);
            }
            if (!string.IsNullOrEmpty(rootName))
            {
                mapper.EndElement();
            }
        }