// ******************************************************************************// // 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 { /// /// RaytheonConfiguration class is used to read in XML file for each instrument. /// The XML file must have 2 main sections and /// 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 /// public class RaytheonXmlConfigurationWrapper { private XElement _rootXelement; /// /// Constructor /// /// /// This string contains the XML tags starting at ... /// This string is obtained from calling _configuration.GetXmlConfiguration("[section_name]"); /// public RaytheonXmlConfigurationWrapper(string xElemString) { _rootXelement = XElement.Parse(xElemString); } /// /// Constructor /// private RaytheonXmlConfigurationWrapper() { } /// /// Get the value of an attribute in the element at path /// /// /// Specify / if want to access root element /// Specify /subtag1/subtag2 to access child elements /// /// /// 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; } /// /// Get the value of the element at path /// /// /// Specify / if want to access root element /// Specify /subtag1/subtag2 to access child elements /// /// public string GetValue(string path) { XNode xNode = GetXNode(path); return ((XElement)xNode).Value; } /// /// 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; /// /// /// Specify / if want to access root element /// Specify /subtag1/subtag2 to access child elements /// /// public XElement GetXElement(string path) { XNode xNode = GetXNode(path); return ((XElement)xNode); } /// /// Get XNode of the path /// /// /// Specify / if want to access root element /// Specify /subtag1/subtag2 to access child elements /// /// 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; } } }