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);
}
}
}
}