将xml值映射到枚举类型
本文关键字:枚举 类型 映射 xml | 更新日期: 2023-09-27 17:58:42
我需要将从第三方获得的XML文件解析为C#对象。我收到的一些XML具有枚举值,我希望将其存储在枚举类型中。
例如,我得到了xml文件的以下xsd:
<xsd:simpleType name="brandstof">
<xsd:restriction base="xsd:string">
<!-- Benzine -->
<xsd:enumeration value="B" />
<!-- Diesel -->
<xsd:enumeration value="D" />
<!-- LPG/Gas -->
<xsd:enumeration value="L" />
<!-- LPG G3 -->
<xsd:enumeration value="3" />
<!-- Elektrisch -->
<xsd:enumeration value="E" />
<!-- Hybride -->
<xsd:enumeration value="H" />
<!-- Cryogeen -->
<xsd:enumeration value="C" />
<!-- Overig -->
<xsd:enumeration value="O" />
</xsd:restriction>
</xsd:simpleType>
我想把它映射到一个枚举,我已经做到了:
public enum Fuel
{
B,
D,
L,
E,
H,
C,
O
}
我遇到的问题是xml可能包含3
的值,而我似乎无法将其放入枚举类型中。有没有任何解决方案可以将此值放入枚举中。
我还可以获得其他带有-
或/
的值,并且我想将这些值放入枚举类型中
欢迎阿奴的建议!
使用XmlEnum
属性进行装饰:http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlenumattribute.aspx
public enum Fuel
{
[XmlEnum("B")]
Benzine,
[XmlEnum("D")]
Diesel,
[XmlEnum("L")]
LpgGas,
[XmlEnum("3")]
LpgG3,
[XmlEnum("E")]
Elektrisch,
[XmlEnum("H")]
Hybride,
[XmlEnum("C")]
Cryogeen,
[XmlEnum("O")]
Overig
}
您可以使用将xml属性值解析回枚举类型
var value = Enum.Parse(typeof(Fuel), "B");
但我认为你的"特殊"价值观(3
、a/
等)不会走得太远。为什么不将枚举定义为
enum Fuel
{
Benzine,
Diesel,
// ...
Three,
ASlash,
// ...
}
并编写一个静态方法将字符串转换为枚举成员?
为了实现这样的方法,您可以考虑将自定义属性添加到包含其字符串表示的枚举成员中——如果某个值在枚举中没有确切的对应值,请查找具有该属性的成员。
创建这样的属性很容易:
/// <summary>
/// Simple attribute class for storing String Values
/// </summary>
public class StringValueAttribute : Attribute
{
public string Value { get; private set; }
public StringValueAttribute(string value)
{
Value = value;
}
}
然后你可以在你的枚举中使用它们:
enum Fuel
{
[StringValue("B")]
Benzine,
[StringValue("D")]
Diesel,
// ...
[StringValue("3")]
Three,
[StringValue("/")]
Slash,
// ...
}
这两种方法将帮助您将字符串解析为您选择的枚举成员:
/// <summary>
/// Parses the supplied enum and string value to find an associated enum value (case sensitive).
/// </summary>
public static object Parse(Type type, string stringValue)
{
return Parse(type, stringValue, false);
}
/// <summary>
/// Parses the supplied enum and string value to find an associated enum value.
/// </summary>
public static object Parse(Type type, string stringValue, bool ignoreCase)
{
object output = null;
string enumStringValue = null;
if (!type.IsEnum)
{
throw new ArgumentException(String.Format("Supplied type must be an Enum. Type was {0}", type));
}
//Look for our string value associated with fields in this enum
foreach (FieldInfo fi in type.GetFields())
{
//Check for our custom attribute
var attrs = fi.GetCustomAttributes(typeof (StringValueAttribute), false) as StringValueAttribute[];
if (attrs != null && attrs.Length > 0)
{
enumStringValue = attrs[0].Value;
}
//Check for equality then select actual enum value.
if (string.Compare(enumStringValue, stringValue, ignoreCase) == 0)
{
output = Enum.Parse(type, fi.Name);
break;
}
}
return output;
}
当我在做的时候:这是另一条路;)
/// <summary>
/// Gets a string value for a particular enum value.
/// </summary>
public static string GetStringValue(Enum value)
{
string output = null;
Type type = value.GetType();
if (StringValues.ContainsKey(value))
{
output = ((StringValueAttribute) StringValues[value]).Value;
}
else
{
//Look for our 'StringValueAttribute' in the field's custom attributes
FieldInfo fi = type.GetField(value.ToString());
var attributes = fi.GetCustomAttributes(typeof(StringValueAttribute), false);
if (attributes.Length > 0)
{
var attribute = (StringValueAttribute) attributes[0];
StringValues.Add(value, attribute);
output = attribute.Value;
}
}
return output;
}
为什么不能解析字符串
[XmlAttribute("brandstof")]
public string FuelTypeString
{
get { return fuel.ToString(); }
set
{
fuel = (Fuel)System.Enum.Parse(typeof(Fuel), value);
}
}
[XmlIgnore()]
public Fuel FuelType
{
get { return fuel; }
set { fuel = value; }
}
所以你真的把它序列化为一个字符串。
我创建了一个处理此问题的类:
class EnumCreator
{
public static Type CreateEnum(List<string> AValues)
{
// Get the current application domain for the current thread.
AppDomain currentDomain = AppDomain.CurrentDomain;
// Create a dynamic assembly in the current application domain,
// and allow it to be executed and saved to disk.
AssemblyName aName = new AssemblyName("TempAssembly");
AssemblyBuilder ab = currentDomain.DefineDynamicAssembly(
aName, AssemblyBuilderAccess.RunAndSave);
// Define a dynamic module in "TempAssembly" assembly. For a single-
// module assembly, the module has the same name as the assembly.
ModuleBuilder mb = ab.DefineDynamicModule(aName.Name, aName.Name + ".dll");
// Define a public enumeration with the name "Elevation" and an
// underlying type of Integer.
EnumBuilder eb = mb.DefineEnum("EnumValues", TypeAttributes.Public, typeof(int));
// Define two members, "High" and "Low".
foreach (string v in AValues)
{
eb.DefineLiteral(v, AValues.IndexOf(v));
}
// Create the type and save the assembly.
Type finished = eb.CreateType();
return finished;
}
}
您必须首先读取xml文件并将值放在列表中,例如,您可以使用XElement对象来执行此操作。
//编辑:像这样:
XElement xml = XElement.parse("file.xml");
List<string> enumItems = new List<string>();
foreach(XElement row in xml.Element("xsd:simpleType").Element("xsd:restriction").Elements())
{
enumItems.Add(row.Attribute("value").Value);
}
Type Fuel = EnumCreator.CreatEnum(enumItems);