正确的方式来实现的IXmlSerializable? [英] Proper way to implement IXmlSerializable?

查看:154
本文介绍了正确的方式来实现的IXmlSerializable?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一旦一个程序员决定实施的IXmlSerializable ,什么是它实施的规则和最佳做法?我听说的getSchema()应该返回的ReadXml 返回前应该移动到下一个元素。这是真的?又是怎么回事中WriteXML - 应该把它写该对象的根元素,或者它假设根已经写的?应该如何子对象进行处理,并写?

下面是什么,我现在有一个样本。我得到良好的反应,我会更新它。

 公共类MyCalendar:的IXmlSerializable
{
    私人字符串_name;
    私人布尔_enabled;
    私人色彩_Color;
    私人列表< MyEvent> _events =新的List< MyEvent>();
    公众的XmlSchema的getSchema(){返回NULL; }    公共无效的ReadXml(XmlReader中读取)
    {
        如果(reader.MoveToContent()== XmlNodeType.Element和放大器;&安培; reader.LocalName ==MyCalendar)
        {
            _name =读卡器[名称];
            _enabled = Boolean.Parse(读卡器[已启用]);
            _Color = Color.FromArgb(Int32.Parse(读卡器[颜色));            如果(reader.ReadToDescendant(MyEvent))
            {
                而(reader.MoveToContent()== XmlNodeType.Element和放大器;&安培; reader.LocalName ==MyEvent)
                {
                    MyEvent EVT =新MyEvent();
                    evt.ReadXml(读卡器);
                    _events.Add(EVT);
                }
            }
            reader.Read();
        }
    }    公共无效中WriteXML(XmlWriter的作家)
    {
        writer.WriteAttributeString(名,_name);
        writer.WriteAttributeString(已启用,_enabled.ToString());
        writer.WriteAttributeString(颜色,_color.ToArgb()的ToString());        的foreach(在_events MyEvent EVT)
        {
            writer.WriteStartElement(MyEvent);
            evt.WriteXml(作家);
            writer.WriteEndElement();
        }
    }
}公共类MyEvent:的IXmlSerializable
{
    私人字符串_title;
    私人的DateTime _start;
    私人的DateTime _stop;
    公众的XmlSchema的getSchema(){返回NULL; }    公共无效的ReadXml(XmlReader中读取)
    {
        如果(reader.MoveToContent()== XmlNodeType.Element和放大器;&安培; reader.LocalName ==MyEvent)
        {
            _title =读卡器[标题];
            _start = DateTime.FromBinary(Int64.Parse(读卡器[开始]));
            _stop = DateTime.FromBinary(Int64.Parse(读卡器[停止]));
            reader.Read();
        }
    }    公共无效中WriteXML(XmlWriter的作家)
    {
        writer.WriteAttributeString(标题,_title);
        writer.WriteAttributeString(开始,_start.ToBinary()的ToString());
        writer.WriteAttributeString(停止,_stop.ToBinary()的ToString());
    }
}

相应的样本XML

 < MyCalendar名称=总体规划启用=真颜色= -  14069085>
    < MyEvent标题=写code开始= - 8589241828854775808停止= - 8589241756854775808/>
    < MyEvent标题=???开始= - 8589241828854775808停止= - 8589241756854775808/>
    < MyEvent标题=利润!开始= - 8589247048854775808停止= - 8589246976854775808/>
< / MyCalendar>


解决方案

是的,的getSchema()<一href=\"http://msdn.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable.getschema.aspx\">should返回null 。


  

IXmlSerializable.GetSchema此方法
  方法是保留,不应该
  用过的。实施当
  IXmlSerializable的界面,你应该
  返回空引用(在没有
  Visual Basic)中从该方法中,而代之以
  如果指定自定义模式是
  需要应用
  XmlSchemaProviderAttribute到
  类。


有关读取和写入,对象元素已编写的,因此你不需要在写增加一个外部因素。例如,你可以开始阅读/两个写属性。

有关<一个href=\"http://msdn.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable.writexml.aspx\">write:


  

在实施中WriteXML你
  提供应写出来的XML
  重新对象的presentation。该
  框架写一个包装元素和
  定位后XML编写的
  开始。你的实现可能会写
  它的内容,包括儿童
  元素。该框架然后关闭
  包装元素。


和对<一个href=\"http://msdn.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable.readxml.aspx\">read:


  

ReadXml方法必须重组
  利用这些信息,你的对象
  写由WriteXml方法。


  
  

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


我会同意这是一个有点不清楚,但它归结为这是你的工作就是阅读()包装年底元素标签。

Once a programmer decides to implement IXmlSerializable, what are the rules and best practices for implementing it? I've heard that GetSchema() should return null and ReadXml should move to the next element before returning. Is this true? And what about WriteXml - should it write a root element for the object or is it assumed that the root is already written? How should child objects be treated and written?

Here's a sample of what I have now. I'll update it as I get good responses.

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());
    }
}

Corresponding Sample 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>

解决方案

Yes, GetSchema() should return null.

IXmlSerializable.GetSchema Method This method is reserved and should not be used. When implementing the IXmlSerializable interface, you should return a null reference (Nothing in Visual Basic) from this method, and instead, if specifying a custom schema is required, apply the XmlSchemaProviderAttribute to the class.

For both read and write, the object element has already been written, so you don't need to add an outer element in write. For example, you can just start reading/writing attributes in the two.

For write:

The WriteXml implementation you provide should write out the XML representation of the object. The framework writes a wrapper element and positions the XML writer after its start. Your implementation may write its contents, including child elements. The framework then closes the wrapper element.

And for read:

The ReadXml method must reconstitute your object using the information that was written by the WriteXml method.

When this method is called, the reader is positioned at the start of the element that wraps the information for your type. That is, just before the start tag that indicates the beginning of a serialized object. When this method returns, it must have read the entire element from beginning to end, including all of its contents. Unlike the WriteXml method, the framework does not handle the wrapper element automatically. Your implementation must do so. Failing to observe these positioning rules may cause code to generate unexpected runtime exceptions or corrupt data.

I'll agree that is a little unclear, but it boils down to "it is your job to Read() the end-element tag of the wrapper".

这篇关于正确的方式来实现的IXmlSerializable?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆