private void LoadInternal(string dataPath) { if (!File.Exists(dataPath)) { return; } var document = new XmlDocument(); document.Load(dataPath); if (document.DocumentElement == null) { return; } if (!document.DocumentElement.HasChildNodes) { return; } foreach (var dataListNode in document.DocumentElement.ChildNodes.OfType <XmlElement>()) { foreach (var dataNode in dataListNode.ChildNodes.OfType <XmlElement>()) { var dataNodeName = DataTemplateDefine.GetDataTemplateNameFromDataNode(dataNode); var dataTemplate = _define.Templates.Single(e => e.Name.Equals(dataNodeName)); var dataObject = ReadObjectFromXml(dataNode, null, dataTemplate); if (dataObject == null) { continue; } var dataClassName = _define.GetCanonicalName(dataTemplate); var dataType = TypeMap[dataClassName]; Debug.Assert(dataObject is IData, "dataObject is IData"); if (!_storage.ContainsKey(dataType)) { _storage.Add(dataType, new List <IData>()); } _storage[dataType].Add(dataObject as IData); } } }
private object ReadObjectFromXml(XmlNode dataNode, Type parentType, DataTemplate template) { var dataClassName = _define.GetCanonicalName(template); Type dataType; if (parentType == null) { if (!TypeMap.ContainsKey(dataClassName)) { return(null); } dataType = TypeMap[dataClassName]; } else { dataType = parentType.GetNestedType(dataClassName); } var idEnumType = dataType.GetNestedType("Ids"); var hasIdEnum = idEnumType != null; var dataObject = Activator.CreateInstance(dataType); if (dataNode.Attributes != null) { foreach (var attribute in dataNode.Attributes.OfType <XmlAttribute>()) { var attributeName = attribute.Name.ToCamelCase(); var attributeProperty = dataType.GetProperty(attributeName); if (attributeProperty == null) { continue; } var isIdAttribute = attributeProperty.Name.Equals("Id"); if (attributeProperty.PropertyType.IsEnum || (isIdAttribute && hasIdEnum)) { var enumString = attribute.Value.Substring(1); // remove leading _ character. var enumType = isIdAttribute ? idEnumType : attributeProperty.PropertyType; Debug.Assert(enumType != null); var enumValue = Enum.Parse(enumType, enumString, true); attributeProperty.SetValue(dataObject, Convert.ChangeType(enumValue, attributeProperty.PropertyType)); } else { attributeProperty.SetValue(dataObject, Convert.ChangeType(attribute.Value, attributeProperty.PropertyType)); } } } if (dataNode.HasChildNodes) { var childNode = dataNode.FirstChild; if (childNode is XmlText) { var textProperty = dataType.GetProperty("Text"); textProperty.SetValue(dataObject, dataNode.FirstChild.Value); } else { var listMap = new Dictionary <PropertyInfo, IList>(); foreach (var childDataNode in childNode.ChildNodes.OfType <XmlElement>()) { var childNodeName = DataTemplateDefine.GetDataTemplateNameFromDataNode(childDataNode); var childTemplate = template.Children.Single(e => e.Name.Equals(childNodeName)); var childClassName = _define.GetCanonicalName(childTemplate); var listProperty = dataType.GetProperty(childClassName + "s"); if (!listMap.ContainsKey(listProperty)) { listMap.Add(listProperty, Activator.CreateInstance(listProperty.PropertyType) as IList); } var childObject = ReadObjectFromXml(childDataNode, dataType, childTemplate); if (childObject == null) { continue; } listMap[listProperty].Add(childObject); } foreach (var pair in listMap) { pair.Key.SetValue(dataObject, pair.Value); } } } return(dataObject); }