// 处理一个类的所有属性反序列化。如果当前深度大于等于父级的深度,则说明已经走到了当前项的最后一行,如果这行是EndElement,则read,跳转到下一行。 // 读取顺序:进入某个Element后,先检查所有的Attribute,填充到对象中;然后跳到下一行。 // 如果下个 private static void FillDataToObject(XmlReader reader, object objectData, Dictionary <string, Type> typeMapping) { int currentDepth = reader.Depth; Type dataType = typeMapping[GetTypeName(objectData.GetType())]; if (reader.HasAttributes) { foreach (PropertyInfo propertyInfo in dataType.GetProperties()) { string propertyName = GetTypeName(propertyInfo.PropertyType); Type propertyType = typeMapping.ContainsKey(propertyName) ? typeMapping[propertyName] : propertyInfo.PropertyType; SerializationIgnoreAttribute ignoreAttribute = propertyInfo.GetCustomAttribute <SerializationIgnoreAttribute>(); GenericCollectionAttribute collectionAttribute = propertyType.GetCustomAttribute <GenericCollectionAttribute>(); // 值类型、字符串、枚举类型,并且未被ignore的非集合属性直接用值转换器处理 if ((propertyInfo.PropertyType.IsValueType || typeof(string).Equals(propertyInfo.PropertyType) || propertyInfo.PropertyType.IsEnum) && null == ignoreAttribute && null == collectionAttribute) { string attribute = reader.GetAttribute(propertyInfo.Name); if (null == attribute) { continue; } FillValueToObject(propertyInfo, objectData, attribute); } } } int propertyNodeDepth = currentDepth + 1; bool readNotOver = reader.Read(); if (!readNotOver) { return; } // xml层级等于或者小于父节点时应该交给上一层的调用处理 while (reader.Depth > currentDepth) { // 如果不是节点或者是空节点或者是结束节点,则继续下一行读取 if (reader.NodeType != XmlNodeType.Element || (reader.IsEmptyElement && !reader.HasAttributes) || reader.NodeType == XmlNodeType.EndElement) { readNotOver = reader.Read(); if (!readNotOver) { return; } continue; } string propertyName = reader.Name; PropertyInfo propertyInfo = dataType.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public); string propertyTypeName = GetTypeName(propertyInfo.PropertyType); if (reader.Depth != propertyNodeDepth || null == propertyInfo || !typeMapping.ContainsKey(propertyTypeName)) { I18N i18N = I18N.GetInstance(Constants.I18nName); throw new TestflowDataException(ModuleErrorCode.DeSerializeFailed, i18N.GetStr("IllegalFileData")); } object propertyObject = CreateTypeInstance(typeMapping, propertyTypeName); propertyInfo.SetValue(objectData, propertyObject); Type propertyType = typeMapping[propertyTypeName]; GenericCollectionAttribute collectionAttribute = propertyType.GetCustomAttribute <GenericCollectionAttribute>(); if (null == collectionAttribute) { FillDataToObject(reader, propertyObject, typeMapping); } else { FillDataToCollection(reader, propertyObject, typeMapping, collectionAttribute.GenericType, propertyObject.GetType()); } } if (reader.NodeType == XmlNodeType.EndElement) { reader.Read(); } }
private static void WriteClassData(string dataName, object dataValue, XmlWriter writer) { // 如果属性为null则返回不写入内容 if (null == dataValue) { return; } writer.WriteStartElement(dataName); Type dataType = dataValue.GetType(); List <PropertyInfo> collectionProperties = new List <PropertyInfo>(10); List <Type> collectionElemType = new List <Type>(10); List <PropertyInfo> classProperties = new List <PropertyInfo>(10); SerializationOrderEnableAttribute orderEnableAttr = dataType.GetCustomAttribute <SerializationOrderEnableAttribute>(); PropertyInfo[] properties = dataType.GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach (PropertyInfo propertyInfo in properties) { object propertyValue = propertyInfo.GetValue(dataValue); if (null == propertyValue) { continue; } Type propertyType = propertyValue.GetType(); XmlIgnoreAttribute xmlIgnoreAttribute = propertyInfo.GetCustomAttribute <XmlIgnoreAttribute>(); SerializationIgnoreAttribute ignoreAttribute = propertyInfo.GetCustomAttribute <SerializationIgnoreAttribute>(); GenericCollectionAttribute collectionAttribute = propertyType.GetCustomAttribute <GenericCollectionAttribute>(); if (null != xmlIgnoreAttribute || (null != ignoreAttribute && ignoreAttribute.Ignore)) { continue; } // 集合类型的数据和类类型的数据在后面写入 if (null != collectionAttribute) { collectionProperties.Add(propertyInfo); collectionElemType.Add(collectionAttribute.GenericType); } else if (propertyType.IsClass && !typeof(string).Equals(propertyType)) { classProperties.Add(propertyInfo); } else if (propertyType.IsEnum) { WriteValueData(propertyInfo.Name, propertyValue.ToString(), writer); } else { WriteValueData(propertyInfo.Name, propertyValue, writer); } } // 如果该对象需要对属性进行排序写入,则先写入已配置顺序的属性 if (null != orderEnableAttr && orderEnableAttr.OrderEnable) { WriteOrderEnabledProperties(dataValue, writer, collectionProperties, collectionElemType, classProperties); } // 写入类信息 foreach (PropertyInfo propertyInfo in classProperties) { WriteClassData(propertyInfo.Name, propertyInfo.GetValue(dataValue), writer); } // 写入集合信息 for (int i = 0; i < collectionProperties.Count; i++) { WriteCollectionData(collectionProperties[i].Name, collectionProperties[i].GetValue(dataValue), collectionElemType[i], writer); } writer.WriteEndElement(); }