我从第三方获得了xml,我需要将其反序列化为C#对象。此xml可能包含具有整数类型值或空值的属性:attr =” 11”或attr =””。我想将此属性值反序列化为具有可空整数类型的属性。但是XmlSerializer不支持反序列化为可空类型。在使用InvalidOperationException {“发生错误,反映类型'TestConsoleApplication.SerializeMe'。”}的XmlSerializer创建期间,以下测试代码失败。
[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);
}
}
当我将“值”属性的类型更改为int时,反序列化失败,并显示InvalidOperationException:
XML文档(1,16)中有错误。
有人可以建议如何将具有空值的属性反序列化为可空类型(作为null),同时将非空属性值反序列化为整数吗?有什么技巧可以使我不必手动对每个字段进行反序列化(实际上有很多)吗?
ahsteele发表评论后更新:
-
据我所知,此属性仅与XmlElementAttribute一起使用-此属性指定该元素不包含任何内容,无论是子元素还是正文。但是我需要找到XmlAttributeAttribute的解决方案。无论如何,我无法更改xml,因为我无法控制它。
-
仅当属性值为非空或缺少属性时,此属性才起作用。当attr具有空值(attr ='')时,XmlSerializer构造函数将失败(如预期的那样)。
public class Element { [XmlAttribute("attr")] public int Value { get; set; } [XmlIgnore] public bool ValueSpecified; }
自定义Nullable类,如Alex Scordellis在此博客文章中所述
我试图通过本博客文章中的课程来解决我的问题:
[XmlAttribute("attr")] public NullableInt Value { get; set; }
但是XmlSerializer构造函数因InvalidOperationException而失败:
无法序列化类型为TestConsoleApplication.NullableInt的成员“ Value”。
XmlAttribute / XmlText不能用于对实现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接口。
目前看来,我必须为整个Element类实现IXmlSerializable(它很大),并且没有简单的解决方法……