/// <summary> /// 读取选项配置文件中的XML内容。 /// </summary> /// <param name="reader">在选项配置文件中进行读取操作的<seealso cref="System.Xml.XmlReader"/>读取器。</param> protected internal virtual void DeserializeElement(XmlReader reader) { if(reader.ReadState == ReadState.Initial) { if(!reader.Read()) throw new OptionConfigurationException(); } OptionConfigurationProperty property; if(reader.NodeType == XmlNodeType.Element) { var elementName = reader.Name; for(int i = 0; i < reader.AttributeCount; i++) { reader.MoveToAttribute(i); //XML特性名中间含点的,并且是以表示是以元素名打头的,则表示为系统内置特性因而无需解析处理 if(reader.Name.StartsWith(elementName + ".")) continue; //获取当前XML元素特性对应的配置属性定义项 if(this.Properties.TryGetValue(reader.Name, out property)) this.SetPropertyValue(property, reader.Value); else { //执行处理未知的属性反序列化 if(!this.OnDeserializeUnrecognizedAttribute(reader.Name, reader.Value)) throw new OptionConfigurationException(string.Format("The '{0}' option configuration attribute is unrecognized.", reader.Name)); } } //将当前读取器移到元素上 reader.MoveToElement(); } //如果当前XML元素是空元素(即其没有子节点的元素),则返回 if(reader.IsEmptyElement) return; //定义当前读取器的初始深度 int depth = reader.Depth; //定义当前待解析子元素的当前配置项元素 OptionConfigurationElement element = this; while(reader.Read() && reader.Depth > depth) { if(reader.NodeType != XmlNodeType.Element) continue; if(reader.Depth == depth + 1) element = this; //如果当前配置项元素是配置集合,则约定当前读取器所处的位置应当处于其下的集合元素的XML节点处 if(typeof(OptionConfigurationElementCollection).IsAssignableFrom(element.GetType())) { //使用当前配置集合来解析当前读取器所处的XML节点内容 element.DeserializeElement(reader.ReadSubtree()); //忽略后续操作,直接进行后续XML内容处理 continue; } //根据当前XML元素名获取对应的配置属性定义项,如果获取失败则获取当前配置项中的默认集合属性定义项 if(!element.Properties.TryGetValue(reader.Name, out property)) property = OptionConfigurationUtility.GetDefaultCollectionProperty(element.Properties); //如果对应的配置属性定义项均获取失败则抛出异常 if(property == null) throw new OptionConfigurationException(string.Format("The '{0}' option configuration element is unrecognized.", reader.Name)); //获取或创建当前配置属性定义项对应的目标元素对象 element = element.EnsureElementPropertyValue(property); //判断获取的配置项元素是否为配置项集合 var collection = element as OptionConfigurationElementCollection; if(collection != null) { //如果当前配置项集合不是默认集合(即集合有对应的XML节点),则将当前读取器移动到其下的子元素的XML节点上 if(!property.IsDefaultCollection) reader.ReadToDescendant(string.IsNullOrWhiteSpace(property.ElementName) ? collection.ElementName : property.ElementName); } //调用当前配置元素对象的反序列化方法 element.DeserializeElement(reader.ReadSubtree()); } }
/// <summary> /// 读取选项配置文件中的XML内容。 /// </summary> /// <param name="reader">在选项配置文件中进行读取操作的<seealso cref="System.Xml.XmlReader"/>读取器。</param> protected internal virtual void DeserializeElement(XmlReader reader) { if (reader.ReadState == ReadState.Initial) { if (!reader.Read()) { throw new OptionConfigurationException(); } } OptionConfigurationProperty property; //反序列化当前元素的Attributes到当前元素的属性集 this.DeserializeAttributes(reader, this); //如果当前XML元素是空元素(即其没有子节点的元素),则返回 if (reader.IsEmptyElement) { return; } //定义当前读取器的初始深度 int depth = reader.Depth; //定义当前待解析子元素的当前配置项元素 OptionConfigurationElement element = this; while (reader.Read() && reader.Depth > depth) { if (reader.NodeType != XmlNodeType.Element) { continue; } if (reader.Depth == depth + 1) { element = this; } //如果当前配置项元素是配置集合,则约定当前读取器所处的位置应当处于其下的集合元素的XML节点处 if (typeof(OptionConfigurationElementCollection).IsAssignableFrom(element.GetType())) { //使用当前配置集合来解析当前读取器所处的XML节点内容 element.DeserializeElement(reader.ReadSubtree()); //忽略后续操作,直接进行后续XML内容处理 continue; } //根据当前XML元素名获取对应的配置属性定义项,如果获取失败则获取当前配置项中的默认集合属性定义项 if (!element.Properties.TryGetValue(reader.Name, out property)) { property = OptionConfigurationUtility.GetDefaultCollectionProperty(element.Properties); } //如果对应的配置属性定义项均获取失败则抛出异常 if (property == null) { throw new OptionConfigurationException(string.Format("The '{0}' option configuration element is unrecognized.", reader.Name)); } //获取或创建当前配置属性定义项对应的目标元素对象 element = element.EnsureElementPropertyValue(property); //判断获取的配置项元素是否为配置项集合 var collection = element as OptionConfigurationElementCollection; if (collection != null) { //如果当前配置项集合不是默认集合(即集合有对应的XML节点),则将当前读取器移动到其下的子元素的XML节点上 if (!property.IsDefaultCollection) { //反序列化当前元素中的Attributes到元素属性集中 this.DeserializeAttributes(reader, element); //将当前读取器移动到集合成员元素上 reader.ReadToDescendant(string.IsNullOrWhiteSpace(property.ElementName) ? collection.ElementName : property.ElementName); } } //调用当前配置元素对象的反序列化方法 element.DeserializeElement(reader.ReadSubtree()); } }