238 lines
7.4 KiB
C#
238 lines
7.4 KiB
C#
/*-------------------------------------------------------------------------
|
|
// 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
|
|
{
|
|
/// <summary>
|
|
/// A XML Wrapper class to create/modify XML files
|
|
/// </summary>
|
|
internal class XmlDocumentWrapper
|
|
{
|
|
public enum AddNodePosition
|
|
{
|
|
First,
|
|
Last
|
|
}
|
|
|
|
private XmlDocument _xmlDoc = null;
|
|
private string _xmlFilePath = String.Empty;
|
|
private object _syncObj = new object();
|
|
|
|
/// <summary>
|
|
/// Constructor
|
|
/// </summary>
|
|
/// <param name="xmlFilePath">XML file path</param>
|
|
/// <param name="rootNodeName">name of the root node.</param>
|
|
public XmlDocumentWrapper(string xmlFilePath, string rootNodeName = "root")
|
|
{
|
|
_xmlFilePath = xmlFilePath;
|
|
CreateXmlDocument(rootNodeName);
|
|
|
|
_xmlDoc = new XmlDocument();
|
|
_xmlDoc.Load(xmlFilePath);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create XML document if it doesn't exist
|
|
/// </summary>
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save XML document to file
|
|
/// </summary>
|
|
public void SaveToFile()
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
using (TextWriter sw = new StreamWriter(_xmlFilePath, false, Encoding.UTF8))
|
|
{
|
|
_xmlDoc.Save(sw);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add a node defined by {path}
|
|
/// </summary>
|
|
/// <param name="path">example: /root/node1/node2</param>
|
|
/// <param name="attributesDict">a dictionary of [name,value] pairs</param>
|
|
/// <param name="innerText">text of the node</param>
|
|
public void AddNode(string path, Dictionary<string, string> 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<XmlAttribute> attributes = new List<XmlAttribute>();
|
|
|
|
foreach (KeyValuePair<string, string> item in attributesDict)
|
|
{
|
|
XmlAttribute attr = _xmlDoc.CreateAttribute(item.Key);
|
|
attr.Value = item.Value;
|
|
|
|
attributes.Add(attr);
|
|
}
|
|
|
|
SetAttrSafe(elem, attributes.ToArray());
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove a node
|
|
/// </summary>
|
|
public void RemoveNode(XmlNode node)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
node.ParentNode.RemoveChild(node);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Change attributes and/or inner text of an existing node
|
|
/// </summary>
|
|
public void ChangeNode(XmlNode node, Dictionary<string, string> attributesDict = null, string innerText = null)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
if (!String.IsNullOrEmpty(innerText))
|
|
node.InnerText = innerText;
|
|
|
|
if (attributesDict != null)
|
|
{
|
|
List<XmlAttribute> attributes = new List<XmlAttribute>();
|
|
|
|
foreach (KeyValuePair<string, string> item in attributesDict)
|
|
{
|
|
XmlAttribute attr = _xmlDoc.CreateAttribute(item.Key);
|
|
attr.Value = item.Value;
|
|
|
|
attributes.Add(attr);
|
|
}
|
|
|
|
SetAttrSafe(node, attributes.ToArray());
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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
|
|
/// </summary>
|
|
/// <param name="path">example: /root/node1/node2</param>
|
|
public XmlNode GetNode(string path)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
return _xmlDoc.SelectSingleNode(path);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get all the nodes matching the path
|
|
/// Useful for iterating through the matched nodes
|
|
/// </summary>
|
|
/// <param name="path">example: /root/node1/node2</param>
|
|
public XmlNodeList GetNodes(string path)
|
|
{
|
|
lock (_syncObj)
|
|
{
|
|
return _xmlDoc.SelectNodes(path);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set attribute
|
|
/// </summary>
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add a node using {xpath}
|
|
/// </summary>
|
|
/// <param name="xpath">example: /root/node1/node2</param>
|
|
private XmlNode MakeXPath(XmlDocument doc, string xpath, AddNodePosition addNodePosition)
|
|
{
|
|
return MakeXPath(doc, doc as XmlNode, xpath, addNodePosition);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Iterate through each node in {xpath} and create them
|
|
/// </summary>
|
|
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);
|
|
}
|
|
}
|
|
}
|