我从第三方获得一个xml,我需要将其反序列化为C#object.此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:
XML文档(%1,%16)中存在错误.
有人能建议如何在将非空属性值反序列化为整数的同时,将具有空值的属性反序列化为可空类型(作为null)?有什么诀窍可以让我不必手动反序列化每个字段(实际上有很多字段)?
ahsteele发表 comments 后更新:
-
据我所知,该属性仅适用于XmlElementAttribute——该属性指定元素没有内容,无论是子元素还是正文.但我需要找到XmlAttributeAttribute的解决方案.无论如何,我无法更改xml,因为我无法控制它.
-
仅当属性值非空或缺少属性时,此属性才起作用.当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:
无法序列化TestConsoleApplication类型的成员"Value".NullableInt.
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; } }
但我不想提出这样的解决方案,因为它 destruct 了我的类对其用户的接口.我最好手动实现IXmlSerializable接口.
目前看来,我必须为整个元素类实现IXmlSerializable(它很大),而且没有简单的解决方法…