using System; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Xml; namespace winsw.Util { public class XmlHelper { /// /// Retrieves a single string element /// /// Parent node /// Element name /// If optional, don't throw an exception if the element is missing /// String value or null /// The required element is missing public static string? SingleElement(XmlNode node, string tagName, bool optional) { XmlNode? n = node.SelectSingleNode(tagName); if (n is null && !optional) throw new InvalidDataException("<" + tagName + "> is missing in configuration XML"); return n is null ? null : Environment.ExpandEnvironmentVariables(n.InnerText); } /// /// Retrieves a single node /// /// Parent node /// Element name /// If otional, don't throw an exception if the element is missing /// String value or null /// The required element is missing public static XmlNode? SingleNode(XmlNode node, string tagName, bool optional) { XmlNode? n = node.SelectSingleNode(tagName); if (n is null && !optional) throw new InvalidDataException("<" + tagName + "> is missing in configuration XML"); return n; } /// /// Retrieves a single mandatory attribute /// /// Parent node /// Attribute name /// Attribute value /// The required attribute is missing public static TAttributeType SingleAttribute(XmlElement node, string attributeName) { if (!node.HasAttribute(attributeName)) { throw new InvalidDataException("Attribute <" + attributeName + "> is missing in configuration XML"); } return SingleAttribute(node, attributeName, default); } /// /// Retrieves a single optional attribute /// /// Parent node /// Attribute name /// Default value /// Attribute value (or default) [return: MaybeNull] public static TAttributeType SingleAttribute(XmlElement node, string attributeName, [AllowNull] TAttributeType defaultValue) { if (!node.HasAttribute(attributeName)) return defaultValue; string rawValue = node.GetAttribute(attributeName); string substitutedValue = Environment.ExpandEnvironmentVariables(rawValue); var value = (TAttributeType)Convert.ChangeType(substitutedValue, typeof(TAttributeType)); return value; } /// /// Retireves a single enum attribute /// /// Type of the enum /// Parent node /// Attribute name /// Default value /// Attribute value (or default) /// Wrong enum value public static TAttributeType EnumAttribute(XmlElement node, string attributeName, TAttributeType defaultValue) { if (!node.HasAttribute(attributeName)) return defaultValue; string rawValue = node.GetAttribute(attributeName); string substitutedValue = Environment.ExpandEnvironmentVariables(rawValue); try { var value = Enum.Parse(typeof(TAttributeType), substitutedValue, true); return (TAttributeType)value; } catch (Exception ex) // Most likely ArgumentException { throw new InvalidDataException("Cannot parse <" + attributeName + "> Enum value from string '" + substitutedValue + "'. Enum type: " + typeof(TAttributeType), ex); } } } }