.net – 使用XmlSerializer将空的xml属性值反序列化为可空的int属性

我从第三方得到一个XML,我需要反序列化成C#对象。此xml可能包含带有整数类型或空值的属性:attr =“11”或attr =“”。我想反序列化这个属性值到类型为nullable integer的属性。但XmlSerializer不支持反序列化为可空类型。以下测试代码在使用InvalidOperationException创建XmlSerializer期间失败{“反映类型为”TestConsoleApplication.SerializeMe“的错误。
[XmlRoot("root")]
public class SerializeMe
{
    [XmlElement("element")]
    public Element Element { get; set; }
}

public class Element
{
    [XmlAttribute("attr")]
    public int? Value { get; set; }
}

class Program {
    static void Main(string[] args) {
        string xml = "<root><element attr=''>valE</element></root>";
        var deserializer = new XmlSerializer(typeof(SerializeMe));
        Stream xmlStream = new MemoryStream(Encoding.ASCII.GetBytes(xml));
        var result = (SerializeMe)deserializer.Deserialize(xmlStream);
    }
}

当我将“Value”属性的类型更改为int时,反序列化失败,并返回InvalidOperationException:

There is an error in XML document (1,16).

任何人可以建议如何反序列化属性与空值为可空类型(作为null)同时反序列化非空的属性值为整数?有这里的任何技巧,所以我不必手动地做每个字段反序列化(实际上有很多他们)?

更新后,从ahsteele的注释:

> Xsi:nil attribute

据我所知,这个属性只适用于XmlElementAttribute – 此属性指定元素没有内容,无论是子元素还是主体文本。但我需要找到XmlAttributeAttribute的解决方案。反正我不能改变xml,因为我没有控制它。
> bool *Specified property

此属性仅在属性值非空或属性缺失时工作。当attr具有空值(attr =”)时,XmlSerializer构造函数失败(如预期的那样)。

public class Element
{
    [XmlAttribute("attr")]
    public int Value { get; set; }

    [XmlIgnore]
    public bool ValueSpecified;
}

> Custom Nullable class like in this blog post by Alex Scordellis

我试图采纳从这篇博客的类到我的问题:

[XmlAttribute("attr")]
public NullableInt Value { get; set; }

但XmlSerializer构造函数失败,并返回InvalidOperationException:

Cannot serialize member ‘Value’ of type TestConsoleApplication.NullableInt.

XmlAttribute/XmlText cannot be used to encode types implementing IXmlSerializable }

>丑陋的代理解决方案(耻辱我,我在这里写这个代码:)):

public class Element
{
    [XmlAttribute("attr")]
    public string SetValue { get; set; }

    public int? GetValue()
    {
        if ( string.IsNullOrEmpty(SetValue) || SetValue.Trim().Length <= 0 )
            return null;

        int result;
        if (int.TryParse(SetValue,out result))
            return result;

        return null;
    }
}

但我不想提出这样的解决方案,因为它打破了我的类的消费者的接口。我最好手动实现IXmlSerializable接口。

目前,它看起来像我必须实现IXmlSerializable为整个Element类(它是大),没有简单的解决方法…

这应该工作:
[XmlIgnore]
public int? Age { get; set; }

[XmlElement("Age")]
public string AgeAsText
{
  get { return (Age.HasValue) ? Age.ToString() : null; } 
  set { Age = !string.IsNullOrEmpty(value) ? int.Parse(value) : default(int?); }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


xml怎么加入图片路径
rss源错误怎么解决
文件后缀xml是什么意思
xml格式电子发票怎么获取
xml格式是什么意思
rss是什么意思啊
xml格式电子发票怎么打开
rss订阅源是什么意思
rss源是什么
xml注释怎么写
php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念
xml文件介绍及使用
xml编程(一)-xml语法
XML文件结构和基本语法
第2章 包装类