我从第三方得到一个XML,我需要将其转换为C#对象。此xml可能包含值为整数类型或空值的属性:attr=“11”或attr=""。我想将此属性值转换为类型为可空整数的属性。但是XmlSerializer不支持将其转换为可空类型。以下测试代码在创建XmlSerializer期间失败,并出现InvalidOperationException {“出现反映类型”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评论后更新:
- Xsi:nil attribute
据我所知,这个属性只对XmlElementAttribute起作用--这个属性指定元素没有内容,无论是子元素还是正文文本。但是我需要找到XmlAttributeAttribute的解决方案。无论如何,我不能改变XML,因为我无法控制它。 - bool * 指定属性
仅当属性值非空或缺少属性时,此属性才有效。当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. NullableInt类型的成员“Value”。
XmlAttribute/XmlText不能用于编码实现IXmlSerializable的类型
1.丑陋的代理解决方案(我为我在这里写的代码感到羞耻:)):
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(它很大),而且没有简单的解决办法。
6条答案
按热度按时间ws51t4hk1#
这应该是可行的:
shyt4zoc2#
我通过实现IXmlSerializable接口解决了这个问题。我没有找到更简单的方法。
下面是测试代码示例:
dwbf0jvd3#
最近我自己也一直在搞序列化,发现下面的文章和帖子在处理值类型的空数据时很有帮助。
如何在C#中使用XmlSerializer使值类型可为空- serialization* 的答案详细介绍了XmlSerializer的一个非常漂亮的技巧。具体来说,XmlSerialier查找XXXSpecified布尔属性,以确定是否应包含它,这允许您忽略空值。
Alex Scordellis问了一个StackOverflow问题,得到了很好的回答。Alex还在他的博客上写了一篇关于他试图解决 * Using XmlSerializer to deserialize into a Nullable * 问题的文章。
有关Xsi:nil Attribute Binding Support的MSDN文档也很有用。就像IXmlSerializable Interface的文档一样,尽管编写自己的实现应该是最后的手段。
r8uurelv4#
我想我最好把答案扔到帽子里:通过创建实现IXmlSerializable接口的自定义类型解决了此问题:
假设你有一个XML对象,它有以下节点:
表示它们的对象:
动态可空结构表示任何潜在的可空项沿着转换
z0qdvdin5#
您也可以通过将
xml
加载到XmlDocument
中,然后将其转换为Json
来获得您正在查找的对象T
。to94eoyn6#
我需要将不能修改的xml格式化,它缺少一些属性,我需要使它们可以为空。
我一直在寻找一个简单和有效的解决方案很长一段时间,但不幸的是没有这样的解决方案。我不得不为一个具有可空字段的类编写自己的IXmlSerializable实现。
然后,您只需从XmlNullableSerializable继承您的类。这只适用于非空化,你的类可以包含结构类型的可空字段。范例: