在尝试使用XmlSerializer.Deserialize()方法对特定XML文档进行反序列化时,我遇到了一个非常烦人的问题。
基本上,我有一个强类型的XSD,其元素类型为double。当尝试反序列化特定XML文档的元素时,我得到通常的“System.FormatException:输入字符串格式不正确”。异常,因为在该特定文档中,元素没有值。
这里有一些代码供你书呆子。
示例XML文档:
<TrackInfo>
<Name>Barcelona</Name>
<Length>4591</Length>
<AverageSpeed />
</TrackInfo>
XSD:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="TrackInfo">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="Length" type="xs:double" default="0.0" />
<xs:element name="AverageSpeed" type="xs:double" default="0.0" />
</xs:sequence>
</xs:complexType>
</xs:element>
TrackInfo类:
[Serializable]
public class TrackInfo
{
private string name = string.Empty;
private double length = 0.0;
private double averageSpeed = 0.0;
[XmlElement]
public string Name
{ ... }
[XmlElement]
public double Length
{ ... }
[XmlElement]
public double AverageSpeed
{ ... }
}
示例反序列化代码:
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load("TrackInfo.xml");
// Deserialise XML string into TrackInfo object
byte[] buffer = ASCIIEncoding.UTF8.GetBytes(xmlDocument.InnerXml);
MemoryStream stream = new MemoryStream(buffer);
System.Xml.XmlReader reader = new System.Xml.XmlTextReader(stream);
XmlSerializer xSerializer = new System.Xml.Serialization.XmlSerializer(typeof(TrackInfo));
TrackInfo trackInfo = (TrackInfo)xSerializer.Deserialize(reader);
我知道反序列化异常来自于空字符串无法转换为double的事实。我也知道默认值没有分配给AverageSpeed,因为实际上,空字符串是一个完全可以接受的值。
在反序列化时是否有一种简单的方法可以将double值默认为0.0(或任何其他类型),如果在XML文档中找到空字符串值? 理想情况下,我想避免实现ISerializable,因为我真的不想把剩下的时间花在地狱的燃烧坑上(即实现大约一百个类的ISerializable)。
干杯! 让 - 米歇尔
答案 0 :(得分:3)
查看DefaultValueAttribute上的MSDN文档: http://msdn.microsoft.com/en-us/library/system.componentmodel.defaultvalueattribute.aspx
注意: DefaultValueAttribute不会导致成员 自动初始化 属性的值。你必须设置 代码中的初始值。
我认为字段初始化将始终优先于DefaultValueAttribute值。无论如何,这似乎正是我所寻找的。 p>
非常感谢塞巴斯蒂安!
答案 1 :(得分:1)
一种可能的解决方案是使用 double?(带问号,或Nullable&lt; double&gt;)。这允许您的值类型存储空值,并且反序列化器不会阻塞空值。
答案 2 :(得分:1)
您可以指定默认值,如
[XmlElement]
[System.ComponentModel.DefaultValueAttribute(0.0)]
public double AverageSpeed
{ ... }
/编辑:好的,奇怪的是在这里。无论我在属性中设置什么值,它总是字段值:
private double averageSpeed = 2.0;
但没有例外。
答案 3 :(得分:0)
您可以编辑架构以指定AverageSpeed值不可为空。这要求产生XML的任何东西实际上都遵循模式。
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="TrackInfo">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="Length" type="xs:double" default="0.0" />
<xs:element name="AverageSpeed" type="xs:double" default="0.0" nillable="false" />
</xs:sequence>
</xs:complexType>
</xs:element>