/// <summary> /// Loads a script document from the given file /// </summary> /// <param name="File">The file to load</param> /// <param name="Schema">The schema to validate against</param> /// <param name="OutConfigFile">If successful, the document that was read</param> /// <returns>True if the document could be read, false otherwise</returns> public static bool TryRead(FileReference File, XmlSchema Schema, out XmlConfigFile OutConfigFile) { XmlConfigFile ConfigFile = new XmlConfigFile(File); XmlReaderSettings Settings = new XmlReaderSettings(); Settings.Schemas.Add(Schema); Settings.ValidationType = ValidationType.Schema; Settings.ValidationEventHandler += ConfigFile.ValidationEvent; using (XmlReader Reader = XmlReader.Create(File.FullName, Settings)) { // Read the document ConfigFile.LineInfo = (IXmlLineInfo)Reader; try { ConfigFile.Load(Reader); } catch (XmlException Ex) { if (!ConfigFile.bHasErrors) { Log.TraceError(File, Ex.LineNumber, "{0}", Ex.Message); ConfigFile.bHasErrors = true; } } // If we hit any errors while parsing if (ConfigFile.bHasErrors) { OutConfigFile = null; return(false); } // Check that the root element is valid. If not, we didn't actually validate against the schema. if (ConfigFile.DocumentElement.Name != RootElementName) { Log.TraceError("Script does not have a root element called '{0}'", RootElementName); OutConfigFile = null; return(false); } if (ConfigFile.DocumentElement.NamespaceURI != SchemaNamespaceURI) { Log.TraceError("Script root element is not in the '{0}' namespace (add the xmlns=\"{0}\" attribute)", SchemaNamespaceURI); OutConfigFile = null; return(false); } } OutConfigFile = ConfigFile; return(true); }
/// <summary> /// Reads an XML config file and merges it to the given cache /// </summary> /// <param name="Location">Location to read from</param> /// <param name="CategoryToFields">Lookup for configurable fields by category</param> /// <param name="TypeToValues">Map of types to fields and their associated values</param> /// <param name="Schema">Schema to validate against</param> /// <returns>True if the file was read successfully</returns> static bool TryReadFile(FileReference Location, Dictionary <string, Dictionary <string, FieldInfo> > CategoryToFields, Dictionary <Type, Dictionary <FieldInfo, object> > TypeToValues, XmlSchema Schema) { // Read the XML file, and validate it against the schema XmlConfigFile ConfigFile; if (!XmlConfigFile.TryRead(Location, Schema, out ConfigFile)) { return(false); } // Parse the document foreach (XmlElement CategoryElement in ConfigFile.DocumentElement.ChildNodes.OfType <XmlElement>()) { Dictionary <string, FieldInfo> NameToField; if (CategoryToFields.TryGetValue(CategoryElement.Name, out NameToField)) { foreach (XmlElement KeyElement in CategoryElement.ChildNodes.OfType <XmlElement>()) { FieldInfo Field; if (NameToField.TryGetValue(KeyElement.Name, out Field)) { // Parse the corresponding value object Value; if (Field.FieldType == typeof(string[])) { Value = KeyElement.ChildNodes.OfType <XmlElement>().Where(x => x.Name == "Item").Select(x => x.InnerText).ToArray(); } else { Value = ParseValue(Field.FieldType, KeyElement.InnerText); } // Add it to the set of values for the type containing this field Dictionary <FieldInfo, object> FieldToValue; if (!TypeToValues.TryGetValue(Field.DeclaringType, out FieldToValue)) { FieldToValue = new Dictionary <FieldInfo, object>(); TypeToValues.Add(Field.DeclaringType, FieldToValue); } FieldToValue[Field] = Value; } } } } return(true); }
/// <summary> /// Constructor /// </summary> public XmlConfigFileElement(FileReference InFile, int InLineNumber, string Prefix, string LocalName, string NamespaceUri, XmlConfigFile ConfigFile) : base(Prefix, LocalName, NamespaceUri, ConfigFile) { File = InFile; LineNumber = InLineNumber; }