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); }
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(); }
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; }
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(); } }