我知道enum
值可以从字符串或整数值中取消序列化,但不能同时从两者中取消序列化。我想写一些代码来处理enum
解序列化,无论XML中的值是整数还是字符串。下面给出了一个带有示例数据的示例。
数据结构
class Employee
{
public string Name { get; set; }
public RankType Rank { get; set; }
}
enum RankType
{
Junior,
MidLevel,
Senior,
Executive
}
可能的XML数据-示例1
<employee>
<name>John Doe</name>
<rank>Executive</rank>
</employee>
可能的XML数据-示例2
<employee>
<name>John Doe</name>
<rank>3</rank>
</employee>
我写了这段代码,它对样本1很好,但对样本2崩溃了:
var xs = new XmlSerializer(typeof(Employee));
XmlDocument xml = new XmlDocument();
xml.LoadXml(empRequest);
var node = xml.SelectSingleNode("/EmpRequest"); // <-- the exact path here is irrelevant
var sr = new StringReader(xml.InnerXml);
var obj = (Employee)xs.Deserialize(sr); // <-- Exception here
异常消息是:">'3'不是RankType的有效值";
您可以将Employee
类设为IXmlSerializable
,并完全控制它的序列化和反序列化方式
或者您可以在将xml文档传递给XmlSerializer
之前准备好它
例如,搜索所有employeerank
节点,如果它们包含整数,则将其更改为名称。
var xs = new XmlSerializer(typeof(Employee));
XmlDocument xml = new XmlDocument();
xml.LoadXml(empRequest);
// update employee/rank
foreach (XmlElement rankNode in xml.SelectNodes("//employee/rank"))
if (Int32.TryParse(rankNode.InnerText, out int rank) && Enum.IsDefined(typeof(RankType), rank))
rankNode.InnerText = Enum.GetName(typeof(RankType), rank);
// loading further
var node = xml.SelectSingleNode("/EmpRequest");
var sr = new StringReader(node.InnerXml);
var obj = (Employee)xs.Deserialize(sr);
以下内容适用于名称或整数值
class Employee
{
public string Name { get; set; }
private RankType Rank { get; set; }
[XmlElement("Rank")]
public string _Rank {
get {
return Rank.ToString();
//use following if you want integer when serializing
//return ((int)Rank).ToString();
}
set
{
int number = 0;
Boolean numeric = int.TryParse(value, out number);
if (numeric)
{
Rank = (RankType)number;
}
else
{
Rank = (RankType)Enum.Parse(typeof(RankType), value);
}
}
}
enum RankType
{
Junior,
MidLevel,
Senior,
Executive
}