使用字典成员和常规字段为类自定义xml序列化 [英] customize xml serialize for class with Dictionary member and normal fields

查看:81
本文介绍了使用字典成员和常规字段为类自定义xml序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我设计了一个类作为DTO.为了灵活起见,我将其设计为DictionaryBase的子类.

I designed a class as a DTO. For flexible, I design it as the subclass of DictionaryBase.

[XmlRoot("dict")]
public abstract class DictionaryObject<TKey, TValue> : DictionaryBase, IDictionaryObject, IXmlSerializable
{
    public const string XML_INNER_DICT = "innerdict";
    public const string XML_KEY = "key";
    public const string XML_VALUE = "value";

    #region fields

    public string ExtString {get; set; }
    public object ExtObject {get; set; }

    #endregion

    #region indexes

    public virtual TValue this[TKey key]
    {
        get
        {
            return base.Dictionary[key];
        }
        set
        {
            base.Dictionary[key] = value;
        }
    }
    #endregion

    #region IXmlSerializable members
    public virtual XmlSchema GetSchema()
    {
        throw new NotImplementedException();
    }


    public override void ReadXml(XmlReader reader)
    {
        XmlSerializer keySerializer = new XmlSerializer(typeof (TKey));
        XmlSerializer valueSerializer = new XmlSerializer(typeof (TValue));
        bool wasEmpty = reader.IsEmptyElement;
        reader.Read();

        if (wasEmpty)
        {
            return;
        }

        while (reader.NodeType != XmlNodeType.EndElement)
        {
            if (String.Compare(DictionaryObject.XML_INNER_DICT, reader.Name, true) == 0)
            {
                reader.ReadStartElement(DictionaryObject.XML_INNER_DICT);

                while (reader.NodeType != XmlNodeType.EndElement)
                {
                    reader.ReadStartElement(DictionaryObject.XML_KEY);
                    TKey key = (TKey)keySerializer.Deserialize(reader);
                    reader.ReadEndElement();

                    reader.ReadStartElement(DictionaryObject.XML_VALUE);
                    TValue value = (TValue)valueSerializer.Deserialize(reader);
                    reader.ReadEndElement();

                    this.Set(key, value);
                    reader.MoveToContent();
                }

                reader.ReadEndElement();
            }
            else
            {
                // what should I do here, now I skip
                reader.Skip();
            }
        }
    }

    public override void WriteXml(XmlWriter writer)
    {
        XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
        XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

        // what should I do here to serilize other fields

        if (this.Dictionary.Count > 0)
        {
            writer.WriteStartElement(DictionaryObject.XML_INNER_DICT);

            foreach (TKey key in this.Dictionary.Keys)
            {
                writer.WriteStartElement(DictionaryObject.XML_KEY);
                keySerializer.Serialize(writer, key);
                writer.WriteEndElement();

                writer.WriteStartElement(DictionaryObject.XML_VALUE);
                TValue value = this.Get(key);
                valueSerializer.Serialize(writer, value);
                writer.WriteEndElement();
            }

            writer.WriteEndElement();
        }

    }
    #endregion
}



我想为内部字典以及诸如ExtString,ExtObject之类的普通字段自定义xml序列化,我该怎么做才能完成工作.



I want to customize the xml serialization for the inner dictionary as well as normal fields like ExtString, ExtObject, how can I do to get the job done.

推荐答案

我建​​议您将学习如何使用数据合同,这是一种非常易于使用且功能强大的方法.它也是最不介入的,并且提供了支持向后兼容性的好方法.

简而言之,您只需为类型添加一些属性,主要是[DataContract],并添加[DataMember]您要保留的成员.所有库容器均已受支持.

一个重要方面:DataContractSerializer可以序列化和反序列化任何对象图,即使它不是树,也就是如果它包含循环引用.这可能是您的问题之一,可以通过使用数据合同来解决.您只需要设置属性PreserveObjectReferences.请参阅 http://msdn.microsoft.com/en-us/library/system .runtime.serialization.datacontractserializer.aspx [ ^ ].

请参阅 http://msdn.microsoft.com/en-us/library/ms733127.aspx [ ^ ].

请在我倡导这种方法的地方查看我过去的答案:
如何在我的表单应用程序? [ ^ ],
创建属性文件... [
I suggest you learn how to use Data Contract, which is a very easy to use and powerful approach. It is the most non-intrusive, too and provides great way to support backward compatibility.

In short, you simply add some attributes, mostly [DataContract] to your types and [DataMember] the their members you want to persist. All library containers are already supported.

One important aspect: DataContractSerializer can serialize and deserialize any object graph even if it is not a tree, that is, if it contains circular references. It could be one of your problem which is resolved by using Data Contract. You just need to set the property PreserveObjectReferences. See http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.aspx[^].

See http://msdn.microsoft.com/en-us/library/ms733127.aspx[^].

Please also see my past answers where I advocate this approach:
How can I utilize XML File streamwriter and reader in my form application?[^],
Creating a property files...[^].

If you face any problems, ask a follow-up question; I''ll gladly answer.

—SA


这篇关于使用字典成员和常规字段为类自定义xml序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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