使用c#中的Value属性从Xml反序列化枚举

本文关键字:Xml 反序列化 枚举 属性 中的 Value 使用 | 更新日期: 2023-09-27 18:00:35

我正在尝试用C#编写一个用于图书导入的ONIX工具。我从使用Xsd2Code创建类开始,得到了一个包含所有属性的巨大文件,经过一些调整后,在反序列化时不会产生任何错误。

我试图一次性将整个元素反序列化为内存中的一个大对象,然后对它进行处理(例如将它保存到数据库)。

Xsd2Code生成类的方式,除了有很多属性之外,至少对我来说有点奇怪

这里有一个类应该是Product对象的属性:

public partial class NotificationType
{
    public NotificationTypeRefname refname { get; set; }
    public NotificationTypeShortname shortname { get; set; }
    public SourceTypeCode sourcetype { get; set; }
    public List1 Value { get; set; }
}

我想把你的注意力放在这条线上:

    public List1 Value { get; set; }

"List1"是一个枚举,定义如下:

public enum List1
{
    [System.Xml.Serialization.XmlEnum("01")]
    Item01,
    [System.Xml.Serialization.XmlEnum("02")]
    Item02, etc...

我的问题是,在反序列化过程中,除枚举外,所有字段都正确反序列化。

我试着用XmlEnum("NotificationType")等来装饰属性……什么都没有!

这是我的反序列化代码:

var p = new Product();
XmlSerializer pserializer = new XmlSerializer(p.GetType());
object pDeserialized = pserializer.Deserialize(reader);
p = (Product) pDeserialized;

这就是这个元素在XML:中的样子

<NotificationType>03</NotificationType>

C#中Product对象的属性是:

public NotificationType NotificationType { get; set; }

如果我将其更改为:

public List1 NotificationType { get; set; }

反序列化正确地显示了"Item03",这意味着它可以读取XML中的任何内容。如果我像上面一样保留它,NotificationType类的"Value"属性永远不会被填充,并且总是显示Item01(枚举的默认值)。

关于为什么这个Value属性适用于某些类型(字符串)而不适用于枚举,我已经在SO和web搜索中用尽了所有可能的问题。我是不是错过了什么?

很抱歉问题和代码太长。感谢任何人在这个问题上所能透露的信息。我已经坚持了一整天了。

使用c#中的Value属性从Xml反序列化枚举

试试这个:

public partial class NotificationType
{
    public NotificationTypeRefname refname { get; set; }
    public NotificationTypeShortname shortname { get; set; }
    public SourceTypeCode sourcetype { get; set; }
    public List1 Value { get {
        return (List1)Enum.Parse(typeof(List1), 
            Enum.GetName(typeof(List1), int.Parse(List1Value) - 1));
    }}
    [XmlText]
    public string List1Value { get; set; }
}

[更新]

自:

  1. 起初,我也尝试用XmlText属性装饰成员,但出现了以下异常:

    无法序列化类型为的对象"ConsoleApplication1.NotificationType"。请考虑更改的类型来自的XmlText成员"ConsoleApplication1.NotificationType.Value"ConsoleApplication1.List1到字符串或字符串数组。

  2. 你想在答案中避免我最初的方法,

真正的解决方案是,除了将XmlText属性应用于Value之外,所有其他成员都应该用XmlIgnoreAttribute进行装饰。我认为,单独使用XmlText并不是一个有保证的解决方案,因为结果取决于其他成员的存在。

public class NotificationType
{
    [XmlIgnore] // required
    public NotificationTypeRefname refname { get; set; }
    [XmlIgnore] // required
    public NotificationTypeShortname shortname { get; set; }
    [XmlIgnore] // required
    public SourceTypeCode sourcetype { get; set; }
    [XmlText] // required
    public List1 Value { get; set; }
}

尝试将[System.Xml.Serialization.XmlTextAttribute()]添加到public List1 Value { get; set; }属性中。