Files
2025-10-24 15:18:11 -07:00

166 lines
6.1 KiB
C#

// ******************************************************************************//
// 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.
//
// WARNING: THIS DOCUMENT CONTAINS TECHNICAL DATA AND / OR TECHNOLOGY WHOSE
// EXPORT OR DISCLOSURE TO NON-U.S. PERSONS, WHEREVER LOCATED, IS RESTRICTED
// BY THE INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) (22 C.F.R. SECTION
// 120-130) OR THE EXPORT ADMINISTRATION REGULATIONS (EAR) (15 C.F.R. SECTION
// 730-774). THIS DOCUMENT CANNOT BE EXPORTED (E.G., PROVIDED TO A SUPPLIER
// OUTSIDE OF THE UNITED STATES) OR DISCLOSED TO A NON-U.S. PERSON, WHEREVER
// LOCATED, UNTIL A FINAL JURISDICTION AND CLASSIFICATION DETERMINATION HAS
// BEEN COMPLETED AND APPROVED BY RAYTHEON, AND ANY REQUIRED U.S. GOVERNMENT
// APPROVALS HAVE BEEN OBTAINED. VIOLATIONS ARE SUBJECT TO SEVERE CRIMINAL
// PENALTIES.
//
// DOD 5220.22-M, INDUSTRIAL SECURITY MANUAL, CHAPTER 5, SECTION 1 THROUGH 9 :
// FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN OR DOD 5200.1-R,
// INFORMATION SECURITY PROGRAM, CHAPTER 6. FOR UNCLASSIFIED, LIMITED DOCUMENTS
// DESTROY BY ANY METHOD THAT WILL PREVENT DISCLOSURE OF CONTENTS OR
// RECONSTRUCTION OF THE DOCUMENT.
// ****************************************************************************//
using System;
using System.Xml.Linq;
namespace Raytheon.Common
{
/// <summary>
/// RaytheonConfiguration class is used to read in XML file for each instrument.
/// The XML file must have 2 main sections <IniConfiguration> and <XmlConfigurations>
/// However, it's very limited in how it expects the tags to be structured as section and key
/// which makes no sense for XML tags. There's no flexibility to traverse the tree and
/// get values and attributes of a particular tag.
/// So this class is going to allow that flexiblity
/// </summary>
public class RaytheonXmlConfigurationWrapper
{
private XElement _rootXelement;
/// <summary>
/// Constructor
/// </summary>
/// <param name="xElemString">
/// This string contains the XML tags starting at <XmlConfiguration name="[section_name]">...</XmlConfiguration>
/// This string is obtained from calling _configuration.GetXmlConfiguration("[section_name]");
/// </param>
public RaytheonXmlConfigurationWrapper(string xElemString)
{
_rootXelement = XElement.Parse(xElemString);
}
/// <summary>
/// Constructor
/// </summary>
private RaytheonXmlConfigurationWrapper() { }
/// <summary>
/// Get the value of an attribute in the element at path
/// </summary>
/// <param name="path">
/// Specify / if want to access root element
/// Specify /subtag1/subtag2 to access child elements
/// </param>
/// </param>
/// <returns></returns>
public string GetAttribute(string path, string attributeName)
{
XNode xNode = GetXNode(path);
XAttribute attr = ((XElement)xNode).Attribute(attributeName);
if (attr == null)
{
throw new Exception($"XML attribute {attributeName} not found");
}
return attr.Value;
}
/// <summary>
/// Get the value of the element at path
/// </summary>
/// <param name="path">
/// Specify / if want to access root element
/// Specify /subtag1/subtag2 to access child elements
/// </param>
/// <returns></returns>
public string GetValue(string path)
{
XNode xNode = GetXNode(path);
return ((XElement)xNode).Value;
}
/// <summary>
/// Get Xelement. This is useful for traversing sibling nodes
/// Example:
/// // get the first element
/// XElement elem = raytheonConfig.GetXElement("/Fruit");
/// // go to next sibling and get value
/// str = ((XElement) elem.NextNode).Value;
/// </summary>
/// <param name="path">
/// Specify / if want to access root element
/// Specify /subtag1/subtag2 to access child elements
/// </param>
/// <returns></returns>
public XElement GetXElement(string path)
{
XNode xNode = GetXNode(path);
return ((XElement)xNode);
}
/// <summary>
/// Get XNode of the path
/// </summary>
/// <param name="path">
/// Specify / if want to access root element
/// Specify /subtag1/subtag2 to access child elements
/// </param>
/// <returns></returns>
private XNode GetXNode(string path)
{
string[] tags = path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
XNode xNode = _rootXelement;
string traversePath = $"/{_rootXelement.Name.ToString()}/";
foreach (string tag in tags)
{
xNode = ((XElement)xNode).FirstNode;
while (xNode != null && xNode.NodeType != System.Xml.XmlNodeType.Element)
{
xNode = xNode.NextNode;
if (xNode != null && xNode.NodeType == System.Xml.XmlNodeType.Element)
{
traversePath += $"{((XElement)xNode).Name}/";
if (((XElement)xNode).Name != tag)
{
throw new Exception($"Unexpected XML path {traversePath}");
}
}
}
if (xNode == null)
{
throw new Exception($"XML path /{_rootXelement.Name}/{path} not found");
}
}
return xNode;
}
}
}