如何从XML中的字符串或int中取消枚举值的序列化



我知道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
}

最新更新