C# 如何在xml反序列化期间忽略无效的枚举值?

C# 如何在xml反序列化期间忽略无效的枚举值?,c#,.net,enums,xml-deserialization,C#,.net,Enums,Xml Deserialization,我想将xml文档反序列化为类,该类由相关xsd文件生成。我无法控制xml文件的内容 在反序列化过程中,我遇到了一个异常,因为xml文档中的枚举值不符合xsd的要求。我希望反序列化继续进行,并且只接受任何此类错误的默认值,而不是中断。有没有办法做到这一点 编辑: 为了澄清,我试图实现的是:我想从数字发票中读取数据。因此,xml文件的创建是一种黑盒,可能包含flase值,即使结构符合标准。但这并不意味着,每个价值观都有这样的缺陷。异常阻止我读取正确的值,因此我只希望在发生此类错误时通过插入默认值来

我想将xml文档反序列化为类,该类由相关xsd文件生成。我无法控制xml文件的内容

在反序列化过程中,我遇到了一个异常,因为xml文档中的枚举值不符合xsd的要求。我希望反序列化继续进行,并且只接受任何此类错误的默认值,而不是中断。有没有办法做到这一点


编辑: 为了澄清,我试图实现的是:我想从数字发票中读取数据。因此,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);
}