/// <summary> /// Saves the scheme to the specified file. /// </summary> public bool SaveToFile(string fileName, out string errMsg) { try { XmlDocument xmlDoc = new(); XmlDeclaration xmlDecl = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null); xmlDoc.AppendChild(xmlDecl); // view title XmlElement rootElem = xmlDoc.CreateElement("SchemeView"); rootElem.SetAttribute("title", SchemeDoc.Title); xmlDoc.AppendChild(rootElem); // scheme document XmlElement documentElem = xmlDoc.CreateElement("Scheme"); rootElem.AppendChild(documentElem); SchemeDoc.SaveToXml(documentElem); // scheme components HashSet <string> prefixes = new(); XmlElement componentsElem = xmlDoc.CreateElement("Components"); rootElem.AppendChild(componentsElem); foreach (ComponentBase component in Components.Values) { if (component is UnknownComponent unknownComponent) { componentsElem.AppendChild(unknownComponent.XmlNode); } else { Type compType = component.GetType(); CompLibSpec compLibSpec = CompManager.GetSpecByType(compType); // add namespace if (compLibSpec != null && !prefixes.Contains(compLibSpec.XmlPrefix)) { rootElem.SetAttribute("xmlns:" + compLibSpec.XmlPrefix, compLibSpec.XmlNs); prefixes.Add(compLibSpec.XmlPrefix); } // create XML element of component XmlElement componentElem = compLibSpec == null? xmlDoc.CreateElement(compType.Name) /*standard component*/ : xmlDoc.CreateElement(compLibSpec.XmlPrefix, compType.Name, compLibSpec.XmlNs); componentsElem.AppendChild(componentElem); component.SaveToXml(componentElem); } } // scheme images XmlElement imagesElem = xmlDoc.CreateElement("Images"); rootElem.AppendChild(imagesElem); foreach (Image image in SchemeDoc.Images.Values) { XmlElement imageElem = xmlDoc.CreateElement("Image"); imagesElem.AppendChild(imageElem); image.SaveToXml(imageElem); } xmlDoc.Save(fileName); errMsg = ""; return(true); } catch (Exception ex) { errMsg = ex.BuildErrorMessage(CommonPhrases.SaveViewError); return(false); } }
/// <summary> /// Loads the view from the specified stream. /// </summary> public override void LoadView(Stream stream) { // add template bindings as resource if (!string.IsNullOrEmpty(templateArgs.BindingFileName)) { Resources.Add(new ViewResource { Name = nameof(TemplateBindings), Path = templateArgs.BindingFileName }); } // load XML document XmlDocument xmlDoc = new(); xmlDoc.Load(stream); // check data format XmlElement rootElem = xmlDoc.DocumentElement; if (!rootElem.Name.Equals("SchemeView", StringComparison.OrdinalIgnoreCase)) { throw new ScadaException(CommonPhrases.InvalidFileFormat); } // load scheme document if (rootElem.SelectSingleNode("Scheme") is XmlNode schemeNode) { SchemeDoc.LoadFromXml(schemeNode); // update scheme title if (string.IsNullOrEmpty(Title) && !string.IsNullOrEmpty(SchemeDoc.Title)) { Title = SchemeDoc.Title; } } // load scheme components if (rootElem.SelectSingleNode("Components") is XmlNode componentsNode) { HashSet <string> errNodeNames = new(); // node names of unloaded components LoadErrors.AddRange(CompManager.LoadErrors); foreach (XmlNode compNode in componentsNode.ChildNodes) { // create component ComponentBase component = CompManager.CreateComponent(compNode, out string errMsg); if (component == null) { component = new UnknownComponent { XmlNode = compNode }; if (errNodeNames.Add(compNode.Name)) { LoadErrors.Add(errMsg); } } // load component and add it to view component.SchemeView = this; component.LoadFromXml(compNode); Components[component.ID] = component; // get max component ID if (component.ID > maxComponentID) { maxComponentID = component.ID; } } } // load scheme images if (rootElem.SelectSingleNode("Images") is XmlNode imagesNode) { Dictionary <string, Image> images = SchemeDoc.Images; XmlNodeList imageNodes = imagesNode.SelectNodes("Image"); foreach (XmlNode imageNode in imageNodes) { Image image = new(); image.LoadFromXml(imageNode); if (!string.IsNullOrEmpty(image.Name)) { images[image.Name] = image; } } } }