为了账号安全,请及时绑定邮箱和手机立即绑定

实现IXmlSerialable的正确方法?

实现IXmlSerialable的正确方法?

C#
开满天机 2019-06-28 10:16:22
实现IXmlSerialable的正确方法?一旦程序员决定实现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;
查看完整描述

3 回答

?
回首忆惘然

TA贡献1847条经验 获得超11个赞

是,GetSchema()应该返回空.

IXmlSerializable.GetSchema方法此方法是保留的,不应使用。在实现IXmlSerialable接口时,应从此方法返回一个空引用(在VisualBasic中为Nothing),如果需要指定自定义架构,则应将XmlSchemaProviderAttribute应用于该类。

对于读和写,对象元素已经写好了,所以您不需要在写中添加外部元素。例如,您可以在这两个属性中开始读取/写入属性。

为写:

您提供的WriteXml实现应该写出对象的XML表示。该框架编写一个包装器元素,并在其启动后定位XML编写器。您的实现可以编写其内容,包括子元素。然后,框架关闭包装器元素。

而为了朗读,阅读:

ReadXml方法必须使用WriteXml方法编写的信息重新构造对象。

调用此方法时,读取器位于包装类型信息的元素的开头。也就是说,就在表示序列化对象的开始标记之前。当此方法返回时,它必须从头到尾读取整个元素,包括其所有内容。与WriteXml方法不同,框架不会自动处理包装器元素。您的实现必须这样做。不遵守这些定位规则可能会导致代码产生意外的运行时异常或损坏的数据。

我同意这一点有点不清楚,但归根结底是“这是你的工作Read()包装器的结束元素标记“。


查看完整回答
反对 回复 2019-06-28
?
莫回无

TA贡献1865条经验 获得超7个赞

我想补充一点,在我从事的一个项目中,我们发现手动编写外部XML元素是很尴尬的,这也会导致相同类型的对象的XML元素名称不一致。

我们的解决办法是定义我们自己的IXmlSerializable接口,派生自SystemOne,其中添加了一个名为WriteOuterXml()..可以猜到,这个方法只需编写外部元素,然后调用WriteXml(),然后编写元素的结尾。当然,SystemXML序列化程序不会调用此方法,因此只有在我们自己进行序列化时才会有用,因此在您的情况下可能会有帮助,也可能没有帮助。类似地,我们添加了一个ReadContentXml()方法,它没有读取外部元素,只读取其内容。


查看完整回答
反对 回复 2019-06-28
  • 3 回答
  • 0 关注
  • 439 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信