public void UnloadConfiguration(OptionConfiguration configuration) { if (configuration == null) { return; } foreach (var section in configuration.Sections) { foreach (var elementName in section.Children.Keys) { var node = _root.Find(section.Path, elementName); if (node != null) { var option = node.Option; if (option != null && option.Provider == configuration) { node.Option = null; var parent = node.Parent; if (parent != null) { parent.Children.Remove(node); } } } } } }
public static OptionConfiguration Load(Stream stream) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } using (XmlReader reader = XmlReader.Create(stream, new XmlReaderSettings() { CloseInput = true, IgnoreComments = true, IgnoreProcessingInstructions = true, IgnoreWhitespace = true, })) { reader.MoveToContent(); if (reader.NodeType == XmlNodeType.Element && reader.Name != XML_ROOT_ELEMENT) { throw new OptionConfigurationException(); } var configuration = new OptionConfiguration(stream is FileStream ? ((FileStream)stream).Name : string.Empty); while (reader.Read()) { if (reader.NodeType != XmlNodeType.Element) { continue; } switch (reader.Name) { case XML_OPTION_ELEMENT: ResolveOptionElement(reader, configuration); break; case XML_DECLARATION_COLLECTION: ResolveDeclarationsElement(reader, configuration); break; default: throw new OptionConfigurationException(string.Format("Illegal '{0}' element in '{1}' option file.", reader.Name, configuration.FilePath)); } } return(configuration); } }
public void LoadConfiguration(OptionConfiguration configuration) { if (configuration == null) { return; } foreach (var section in configuration.Sections) { //必须先确保选项节对应的空节点被添加 var sectionNode = _root.FindNode(section.Path, token => { if (token.Current == null) { var parent = token.Parent as OptionNode; if (parent != null) { return(parent.Children.Add(token.Name)); } } return(token.Current); }); //在添加了选项上级空节点添加完成之后再添加选项元素的节点 foreach (var elementName in section.Children.Keys) { var node = (OptionNode)_root.FindNode(new string[] { section.Path, elementName }, token => { if (token.Current == null) { var parent = token.Parent as OptionNode; if (parent != null) { return(parent.Children.Add(token.Name, configuration)); } } return(token.Current); }); } } }
private static void ResolveDeclarationsElement(XmlReader reader, OptionConfiguration configuration) { if (reader == null || reader.NodeType != XmlNodeType.Element || reader.Name != XML_DECLARATION_COLLECTION) { return; } var depth = reader.Depth; while (reader.Read() && reader.Depth > depth) { if (reader.NodeType != XmlNodeType.Element) { continue; } if (reader.Name != XML_DECLARATION_ELEMENT) { throw new OptionConfigurationException(string.Format("Invalid '{0}' declaration element in '{1}' option file.", reader.Name, configuration.FilePath)); } if (string.IsNullOrWhiteSpace(reader.GetAttribute(XML_NAME_ATTRIBUTE))) { throw new OptionConfigurationException("The 'name' attribute of declaration element is empty."); } if (string.IsNullOrWhiteSpace(reader.GetAttribute(XML_TYPE_ATTRIBUTE))) { throw new OptionConfigurationException("The 'type' attribute of declaration element is empty."); } var type = Type.GetType(reader.GetAttribute(XML_TYPE_ATTRIBUTE), false); if (type == null) { throw new OptionConfigurationException(string.Format("Invalid '{0}' type of declaration.", reader.GetAttribute(XML_TYPE_ATTRIBUTE))); } OptionConfiguration.Declarations.Add(reader.GetAttribute(XML_NAME_ATTRIBUTE), type); } }
public static OptionConfiguration Open(string filePath, bool createNotExists = false) { if (string.IsNullOrWhiteSpace(filePath)) { throw new ArgumentNullException(nameof(filePath)); } return(_cache.Get(filePath.Trim(), key => { if (File.Exists(key)) { return OptionConfiguration.Load(key); } if (createNotExists) { return new OptionConfiguration(key); } return null; })); }
private static void ResolveOptionElement(XmlReader reader, OptionConfiguration configuration) { if (reader == null || reader.NodeType != XmlNodeType.Element || reader.Name != XML_OPTION_ELEMENT) { return; } if (string.IsNullOrWhiteSpace(reader.GetAttribute("path"))) { throw new OptionConfigurationException("The 'path' attribute of option element is empty or unspecified."); } var section = configuration._sections[reader.GetAttribute(XML_PATH_ATTRIBUTE)]; if (section == null) { section = configuration._sections.Add(reader.GetAttribute(XML_PATH_ATTRIBUTE)); } while (reader.Read() && reader.Depth > 1) { if (reader.NodeType != XmlNodeType.Element) { continue; } var typeName = reader.GetAttribute(reader.Name + ".type"); OptionConfigurationElement element = null; if (string.IsNullOrWhiteSpace(typeName)) { element = OptionConfigurationUtility.GetGlobalElement(reader.Name); if (element == null) { throw new OptionConfigurationException(string.Format("The '{0}' is a undeclared option element in the '{1}' file.", reader.Name, configuration._filePath)); } } else { Type type = Type.GetType(typeName, false, true); if (!typeof(OptionConfigurationElement).IsAssignableFrom(type)) { throw new OptionConfigurationException(string.Format("The '{0}' is not a OptionConfigurationElement type, in the '{0}' file.", typeName, configuration._filePath)); } element = (OptionConfigurationElement)Activator.CreateInstance(type); } if (element != null) { //保存当前元素的名称 string elementName = reader.Name; //判断获取的配置项元素是否为配置项集合 var collection = element as OptionConfigurationElementCollection; if (collection == null) { element.DeserializeElement(reader); } else { int depth = reader.Depth; //由于在OptionConfigurationSection中不允许存在默认集合,则此处始终应将读取器移动到其下的子元素的XML节点上 while (reader.Read() && reader.Depth > depth) { if (reader.NodeType == XmlNodeType.Element) { collection.DeserializeElement(reader.ReadSubtree()); } } } //将处理完毕的元素对象加入到当前选项节中 section.Children.Add(elementName, element); } } }