C# 如何在xml反序列化期间忽略无效的枚举值?
我想将xml文档反序列化为类,该类由相关xsd文件生成。我无法控制xml文件的内容 在反序列化过程中,我遇到了一个异常,因为xml文档中的枚举值不符合xsd的要求。我希望反序列化继续进行,并且只接受任何此类错误的默认值,而不是中断。有没有办法做到这一点C# 如何在xml反序列化期间忽略无效的枚举值?,c#,.net,enums,xml-deserialization,C#,.net,Enums,Xml Deserialization,我想将xml文档反序列化为类,该类由相关xsd文件生成。我无法控制xml文件的内容 在反序列化过程中,我遇到了一个异常,因为xml文档中的枚举值不符合xsd的要求。我希望反序列化继续进行,并且只接受任何此类错误的默认值,而不是中断。有没有办法做到这一点 编辑: 为了澄清,我试图实现的是:我想从数字发票中读取数据。因此,xml文件的创建是一种黑盒,可能包含flase值,即使结构符合标准。但这并不意味着,每个价值观都有这样的缺陷。异常阻止我读取正确的值,因此我只希望在发生此类错误时通过插入默认值来
编辑: 为了澄清,我试图实现的是:我想从数字发票中读取数据。因此,xml文件的创建是一种黑盒,可能包含flase值,即使结构符合标准。但这并不意味着,每个价值观都有这样的缺陷。异常阻止我读取正确的值,因此我只希望在发生此类错误时通过插入默认值来完成反序列化 无论是将这些值标记为过时的值,还是使用XmlIgnore标记它们,都不会起作用,因为我收到的下一个xml可能包含正确的值 我希望这有助于澄清问题
现在,我正在使用
System.Xml.Serialization
dll,但我愿意实现任何可以帮助我实现所需行为的库
我得到的例外是:
System.InvalidOperationException:实例验证错误:“x”为
不是xType..的有效值”
引发异常的代码:
XmlSerializer serializer = new xml.XmlSerializer(typeof(MyType));
MyType invoice = serializer.Deserialize(memoryStream) as MyType;
我知道代码没有多大帮助,因此我将添加enum,这是目前存在的问题:
public enum PaymentMeansCodeContentType
{
[System.Xml.Serialization.XmlEnumAttribute("10")]
Item10,
[System.Xml.Serialization.XmlEnumAttribute("20")]
Item20,
[System.Xml.Serialization.XmlEnumAttribute("30")]
Item30,
[System.Xml.Serialization.XmlEnumAttribute("48")]
Item48,
[System.Xml.Serialization.XmlEnumAttribute("49")]
Item49,
[System.Xml.Serialization.XmlEnumAttribute("57")]
Item57,
[System.Xml.Serialization.XmlEnumAttribute("58")]
Item58,
[System.Xml.Serialization.XmlEnumAttribute("59")]
Item59,
ZZZ,
}
这些是使用xsd命令行工具自动生成的:
我需要反序列化的xml为我提供了一个“1”,因此显然是一个无效值。我仍然需要访问xml中的其他有效值,并提供指示哪些值有缺陷的方法。您可以将成员标记为过时
public enum TypeEnum
{
Temperature,
Pressure,
[Obsolete]
Humidity
}
更多信息-正如Martin提到的,如果没有适当的上下文或示例代码,回答这个问题有点困难。但是,您可能希望查看模型属性上的XmlIgnoreAttribute装饰器。有关如何使用的更多详细信息,请参见下面的URL和代码示例:
您可以使用library(可通过nuget获得),而不是默认的
XmlSerializer
,它将在出现错误时设置默认值。我建议您将枚举值存储为字符串,然后自己解析它。这是一个相对简单的实现方法,下面是一个示例:
public enum MyEnum
{
Default, //The default value to apply in the event of an invalid Enum value
[XmlEnumAttribute("10")]
Item10,
[XmlEnumAttribute("20")]
Item20
}
public class MyClass
{
public string Value { get; set; }
public MyEnum EnumValue => (MyEnum)(typeof(MyEnum).GetFields().FirstOrDefault(f =>
f.GetCustomAttribute<XmlEnumAttribute>()?.Name == Value)?
.GetValue(null) ?? MyEnum.Default);
}
公共枚举MyEnum
{
Default,//在枚举值无效时应用的默认值
[XmlEnumAttribute(“10”)]
项目10,
[XmlEnumAttribute(“20”)]
项目20
}
公共类MyClass
{
公共字符串值{get;set;}
public MyEnum EnumValue=>(MyEnum)(typeof(MyEnum).GetFields().FirstOrDefault(f=>
f、 GetCustomAttribute()?.Name==值)?
.GetValue(null)??MyEnum.Default);
}
或者,如果您愿意,也可以设置一个可为空的枚举
public enum MyEnum
{
[XmlEnumAttribute("10")]
Item10,
[XmlEnumAttribute("20")]
Item20
}
public class MyClass
{
public string Value { get; set; }
public MyEnum? EnumValue => (MyEnum?)typeof(MyEnum).GetFields().FirstOrDefault(f =>
f.GetCustomAttribute<XmlEnumAttribute>()?.Name == Value)?
.GetValue(null);
}
公共枚举MyEnum
{
[XmlEnumAttribute(“10”)]
项目10,
[XmlEnumAttribute(“20”)]
项目20
}
公共类MyClass
{
公共字符串值{get;set;}
public MyEnum?EnumValue=>(MyEnum?)typeof(MyEnum).GetFields().FirstOrDefault(f=>
f、 GetCustomAttribute()?.Name==值)?
.GetValue(空);
}
我仍然无法找到我所希望的简单答案,但还是设法找到了一份适合我的工作。最后,我根据可能的值预先验证了XML文件中的每个枚举。如果XML与枚举不匹配,我将错误的值和节点保存到验证结果集中,并使用枚举默认值重写XML。如果没有任何代码或示例数据来复制它,很难对该问题提出建议。“这个问题可以修改成包括这个吗?”马丁我试图把这个问题解释得更清楚一些。我希望有帮助。我正在处理几千行的生成类,因此我认为这些示例不会有多大帮助。@Florian您可能正在寻找XmlSchemaValidator
?检查它,它将忽略任何值,即使是上面提到的@Innat3这样的有效值,如果其他xml向我提供有效值,我需要这些值。遗憾的是,这对我不起作用,因为xml包含的值没有出现在枚举中。
public enum MyEnum
{
[XmlEnumAttribute("10")]
Item10,
[XmlEnumAttribute("20")]
Item20
}
public class MyClass
{
public string Value { get; set; }
public MyEnum? EnumValue => (MyEnum?)typeof(MyEnum).GetFields().FirstOrDefault(f =>
f.GetCustomAttribute<XmlEnumAttribute>()?.Name == Value)?
.GetValue(null);
}