【发布时间】:2010-09-21 17:27:11
【问题描述】:
一旦程序员决定实现IXmlSerializable,实现它的规则和最佳实践是什么?我听说GetSchema() 应该返回null 和ReadXml 应该在返回之前移动到下一个元素。这是真的?那么WriteXml 呢?它应该为对象写一个根元素还是假设根已经写了?子对象应该如何处理和写入?
这是我现在拥有的样本。我会在收到好的回复后更新它。
public class MyCalendar : IXmlSerializable
{
private string _name;
private bool _enabled;
private Color _color;
private List<MyEvent> _events = new List<MyEvent>();
public XmlSchema GetSchema() { return null; }
public void ReadXml(XmlReader reader)
{
if (reader.MoveToContent() == XmlNodeType.Element && reader.LocalName == "MyCalendar")
{
_name = reader["Name"];
_enabled = Boolean.Parse(reader["Enabled"]);
_color = Color.FromArgb(Int32.Parse(reader["Color"]));
if (reader.ReadToDescendant("MyEvent"))
{
while (reader.MoveToContent() == XmlNodeType.Element && reader.LocalName == "MyEvent")
{
MyEvent evt = new MyEvent();
evt.ReadXml(reader);
_events.Add(evt);
}
}
reader.Read();
}
}
public void WriteXml(XmlWriter writer)
{
writer.WriteAttributeString("Name", _name);
writer.WriteAttributeString("Enabled", _enabled.ToString());
writer.WriteAttributeString("Color", _color.ToArgb().ToString());
foreach (MyEvent evt in _events)
{
writer.WriteStartElement("MyEvent");
evt.WriteXml(writer);
writer.WriteEndElement();
}
}
}
public class MyEvent : IXmlSerializable
{
private string _title;
private DateTime _start;
private DateTime _stop;
public XmlSchema GetSchema() { return null; }
public void ReadXml(XmlReader reader)
{
if (reader.MoveToContent() == XmlNodeType.Element && reader.LocalName == "MyEvent")
{
_title = reader["Title"];
_start = DateTime.FromBinary(Int64.Parse(reader["Start"]));
_stop = DateTime.FromBinary(Int64.Parse(reader["Stop"]));
reader.Read();
}
}
public void WriteXml(XmlWriter writer)
{
writer.WriteAttributeString("Title", _title);
writer.WriteAttributeString("Start", _start.ToBinary().ToString());
writer.WriteAttributeString("Stop", _stop.ToBinary().ToString());
}
}
对应的示例 XML
<MyCalendar Name="Master Plan" Enabled="True" Color="-14069085">
<MyEvent Title="Write Code" Start="-8589241828854775808" Stop="-8589241756854775808" />
<MyEvent Title="???" Start="-8589241828854775808" Stop="-8589241756854775808" />
<MyEvent Title="Profit!" Start="-8589247048854775808" Stop="-8589246976854775808" />
</MyCalendar>
【问题讨论】:
-
您能在这个问题中添加一个 xml 示例吗?这将使与代码一起阅读变得更简单。谢谢!
-
如何处理在您的 xml 中的最后一个事件之后有 XML 注释等的情况。即,您是否应该使用检查您是否通读到结束元素的内容来完成 ReadXml() 方法?目前这假设最后一个 Read() 会这样做,但可能并不总是这样。
-
@Rory - 添加了示例。迟到总比没有好?
-
@Greg 好信息。难道您不想让 ReadXml 和 WriteXml 使用不变文化吗?我认为如果用户搬到另一个国家并更改了他们的区域和语言设置,您可能会遇到问题。在这种情况下,代码可能无法正确反序列化。我读过,在进行序列化时始终使用不变文化是最佳实践
标签: c# xml xml-serialization