using System;
using System.Linq;
using System.Reflection;
using System.Xml.Linq;
namespace Novacode
{
internal static class XElementHelpers
{
///
/// Get value from XElement and convert it to enum
///
/// Enum type
internal static T GetValueToEnum(XElement element)
{
if (element == null)
throw new ArgumentNullException("element");
String value = element.Attribute(XName.Get("val")).Value;
foreach (T e in Enum.GetValues(typeof(T)))
{
FieldInfo fi = typeof(T).GetField(e.ToString());
if (fi.GetCustomAttributes(typeof(XmlNameAttribute), false).Count() == 0)
throw new Exception(String.Format("Attribute 'XmlNameAttribute' is not assigned to {0} fields!", typeof(T).Name));
XmlNameAttribute a = (XmlNameAttribute)fi.GetCustomAttributes(typeof(XmlNameAttribute), false).First();
if (a.XmlName == value)
return e;
}
throw new ArgumentException("Invalid element value!");
}
///
/// Convert value to xml string and set it into XElement
///
/// Enum type
internal static void SetValueFromEnum(XElement element, T value)
{
if (element == null)
throw new ArgumentNullException("element");
element.Attribute(XName.Get("val")).Value = GetXmlNameFromEnum(value);
}
///
/// Return xml string for this value
///
/// Enum type
internal static String GetXmlNameFromEnum(T value)
{
if (value == null)
throw new ArgumentNullException("value");
FieldInfo fi = typeof(T).GetField(value.ToString());
if (fi.GetCustomAttributes(typeof(XmlNameAttribute), false).Count() == 0)
throw new Exception(String.Format("Attribute 'XmlNameAttribute' is not assigned to {0} fields!", typeof(T).Name));
XmlNameAttribute a = (XmlNameAttribute)fi.GetCustomAttributes(typeof(XmlNameAttribute), false).First();
return a.XmlName;
}
}
///
/// This attribute applied to enum's fields for definition their's real xml names in DocX file.
///
///
/// public enum MyEnum
/// {
/// [XmlName("one")] // This means, that xml element has 'val="one"'
/// ValueOne,
/// [XmlName("two")] // This means, that xml element has 'val="two"'
/// ValueTwo
/// }
///
[AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
internal sealed class XmlNameAttribute : Attribute
{
///
/// Real xml name
///
public String XmlName { get; private set; }
public XmlNameAttribute(String xmlName)
{
XmlName = xmlName;
}
}
}