/*------------------------------------------------------------------------- // UNCLASSIFIED /*------------------------------------------------------------------------- RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION PROPRIETARY TO RAYTHEON COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. DISCLOSURE TO UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO RAYTHEON COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS CONTENTS SHALL BE FURNISHED OR DISCLOSED TO OR COPIED OR USED BY PERSONS OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF RAYTHEON COMPANY. THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S. GOVERNMENT. UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY. -------------------------------------------------------------------------*/ using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Xml; namespace ProgramLib { /// /// A XML Wrapper class to create/modify XML files /// internal class XmlDocumentWrapper { public enum AddNodePosition { First, Last } private XmlDocument _xmlDoc = null; private string _xmlFilePath = String.Empty; private object _syncObj = new object(); /// /// Constructor /// /// XML file path /// name of the root node. public XmlDocumentWrapper(string xmlFilePath, string rootNodeName = "root") { _xmlFilePath = xmlFilePath; CreateXmlDocument(rootNodeName); _xmlDoc = new XmlDocument(); _xmlDoc.Load(xmlFilePath); } /// /// Create XML document if it doesn't exist /// private void CreateXmlDocument(string rootNodeName) { if (!File.Exists(_xmlFilePath)) { XmlDocument doc = new XmlDocument(); XmlElement root = doc.CreateElement(rootNodeName); doc.AppendChild(root); using (TextWriter sw = new StreamWriter(_xmlFilePath, false, Encoding.UTF8)) { doc.Save(sw); } } } /// /// Save XML document to file /// public void SaveToFile() { lock (_syncObj) { using (TextWriter sw = new StreamWriter(_xmlFilePath, false, Encoding.UTF8)) { _xmlDoc.Save(sw); } } } /// /// Add a node defined by {path} /// /// example: /root/node1/node2 /// a dictionary of [name,value] pairs /// text of the node public void AddNode(string path, Dictionary attributesDict = null, string innerText = null, AddNodePosition addNodePosition = AddNodePosition.Last) { lock (_syncObj) { XmlElement elem = (XmlElement)MakeXPath(_xmlDoc, path, addNodePosition); if (!String.IsNullOrEmpty(innerText)) elem.InnerText = innerText; if (attributesDict != null) { List attributes = new List(); foreach (KeyValuePair item in attributesDict) { XmlAttribute attr = _xmlDoc.CreateAttribute(item.Key); attr.Value = item.Value; attributes.Add(attr); } SetAttrSafe(elem, attributes.ToArray()); } } } /// /// Remove a node /// public void RemoveNode(XmlNode node) { lock (_syncObj) { node.ParentNode.RemoveChild(node); } } /// /// Change attributes and/or inner text of an existing node /// public void ChangeNode(XmlNode node, Dictionary attributesDict = null, string innerText = null) { lock (_syncObj) { if (!String.IsNullOrEmpty(innerText)) node.InnerText = innerText; if (attributesDict != null) { List attributes = new List(); foreach (KeyValuePair item in attributesDict) { XmlAttribute attr = _xmlDoc.CreateAttribute(item.Key); attr.Value = item.Value; attributes.Add(attr); } SetAttrSafe(node, attributes.ToArray()); } } } /// /// Get the first node in {path} /// Useful for iterating through the sibling nodes to find the node with a specific attribute so we can modify the node /// /// example: /root/node1/node2 public XmlNode GetNode(string path) { lock (_syncObj) { return _xmlDoc.SelectSingleNode(path); } } /// /// Get all the nodes matching the path /// Useful for iterating through the matched nodes /// /// example: /root/node1/node2 public XmlNodeList GetNodes(string path) { lock (_syncObj) { return _xmlDoc.SelectNodes(path); } } /// /// Set attribute /// private void SetAttrSafe(XmlNode node, XmlAttribute[] attrList) { foreach (var attr in attrList) { if (node.Attributes[attr.Name] != null) { node.Attributes[attr.Name].Value = attr.Value; } else { node.Attributes.Append(attr); } } } /// /// Add a node using {xpath} /// /// example: /root/node1/node2 private XmlNode MakeXPath(XmlDocument doc, string xpath, AddNodePosition addNodePosition) { return MakeXPath(doc, doc as XmlNode, xpath, addNodePosition); } /// /// Iterate through each node in {xpath} and create them /// private XmlNode MakeXPath(XmlDocument doc, XmlNode parent, string xpath, AddNodePosition addNodePosition) { // grab the next node name in the xpath; or return parent if empty string[] partsOfXPath = xpath.Trim('/').Split('/'); string nextNodeInXPath = partsOfXPath.First(); if (string.IsNullOrEmpty(nextNodeInXPath)) return parent; // get or create the node from the name XmlNode node = parent.SelectSingleNode(nextNodeInXPath); if (partsOfXPath.Length == 1) { if (addNodePosition == AddNodePosition.Last) node = parent.AppendChild(doc.CreateElement(nextNodeInXPath)); else node = parent.PrependChild(doc.CreateElement(nextNodeInXPath)); } // rejoin the remainder of the array as an xpath expression and recurse string rest = String.Join("/", partsOfXPath.Skip(1).ToArray()); return MakeXPath(doc, node, rest, addNodePosition); } } }