Exemplo n.º 1
0
		/// <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());
			}
		}
Exemplo n.º 2
0
        /// <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());
            }
        }