如何序列化包含字典的类?

发布于 2024-10-02 00:37:03 字数 648 浏览 3 评论 0原文

我有以下类:

[Serializable]
public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Dictionary<string, string> Attributes { get; set; }
}

我想使用 XmlSerializer 对其进行序列化并获得以下输出:

<Person>
    <FirstName>John</FirstName>
    <LastName>Doe</LastName>
    <Attributes>
        <PhoneNumber>12345</PhoneNumber>
        <StreetName>...</StreetName>
        <StreetNumber>...</StreetNumber>
        ...
    </Attributes>
</Person>

任何帮助将不胜感激。

I have the following class:

[Serializable]
public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Dictionary<string, string> Attributes { get; set; }
}

I would like to serialize it using XmlSerializer and get the following output:

<Person>
    <FirstName>John</FirstName>
    <LastName>Doe</LastName>
    <Attributes>
        <PhoneNumber>12345</PhoneNumber>
        <StreetName>...</StreetName>
        <StreetNumber>...</StreetNumber>
        ...
    </Attributes>
</Person>

Any help would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

烟织青萝梦 2024-10-09 00:37:04

与 MrFox 的答案类似,这是我过去使用过的一种方法,效果很好。

public class Foo{

     [XmlIgnore()]
     public Dictionary<string,string> Dct{get;set;}

     [XmlAttribute]
     public string SerializedDictionary{
          get{
               StringBuilder s = new StringBuilder();
               foreach(var kvp in Dct){
                    if (s.Length > 0) s.Append("|");
                    s.AppendFormat("{0},{1}", kvp.Key, kvp.Value);
               }
               return s.ToString();
          }
          set{
               string[] aKvps = value.Split('|');
               Dct = new Dictionary<string,string>();
               for(int i=0; i<aKvps.Length; ++i){
                    string aPair = aKvps[i].Split(',');
                    if (aPair.Length == 2)
                         Dct.Add(aPair[0], aPair[1]);
               }
          }
     }

}

我凭记忆输入此内容,并没有尝试对其进行编译,因此可能存在一两个错误。但希望它能传达这个想法。此外,这还假设您的数据的值的键中不包含逗号或竖线。如果是这种情况,此解决方案可能不适合您。

Similar to MrFox's answer, this is a hack I've used in the past that works good enough.

public class Foo{

     [XmlIgnore()]
     public Dictionary<string,string> Dct{get;set;}

     [XmlAttribute]
     public string SerializedDictionary{
          get{
               StringBuilder s = new StringBuilder();
               foreach(var kvp in Dct){
                    if (s.Length > 0) s.Append("|");
                    s.AppendFormat("{0},{1}", kvp.Key, kvp.Value);
               }
               return s.ToString();
          }
          set{
               string[] aKvps = value.Split('|');
               Dct = new Dictionary<string,string>();
               for(int i=0; i<aKvps.Length; ++i){
                    string aPair = aKvps[i].Split(',');
                    if (aPair.Length == 2)
                         Dct.Add(aPair[0], aPair[1]);
               }
          }
     }

}

I typed this up from memory and didn't try to compile it, so there may be a bug or two. But hopefully it gets the idea across. Also, this assumes that your data will not have a comma or a pipe in either the keys of the values. If that's the case, this solution may not work for you.

走走停停 2024-10-09 00:37:04

我以前做过这个:

    /// <summary>
    /// Save all information needed set current game state into given file.
    /// </summary>
    /// <param name="fileName"></param>
    public void save(string fileName)
    {
   Dictionary<string, string> attributes = new Dictionary<string, string>();
   attributes.Add("blue", "very");
   attributes.Add("red", "not");

        Stream stream = File.Open(fileName, FileMode.Create);
        BinaryFormatter bFormatter = new BinaryFormatter();

        // Request the current state of all registered
 // objects and save them into the file.
   foreach (KeyValuePair<string, string> storeOnDisk in attributes)
    bFormatter.Serialize(stream, storeOnDisk);

        stream.Close();
    }

I've done this before:

    /// <summary>
    /// Save all information needed set current game state into given file.
    /// </summary>
    /// <param name="fileName"></param>
    public void save(string fileName)
    {
   Dictionary<string, string> attributes = new Dictionary<string, string>();
   attributes.Add("blue", "very");
   attributes.Add("red", "not");

        Stream stream = File.Open(fileName, FileMode.Create);
        BinaryFormatter bFormatter = new BinaryFormatter();

        // Request the current state of all registered
 // objects and save them into the file.
   foreach (KeyValuePair<string, string> storeOnDisk in attributes)
    bFormatter.Serialize(stream, storeOnDisk);

        stream.Close();
    }
望她远 2024-10-09 00:37:04

为什么不使用ProtocolBuffer来序列化。它是开源和免费的平台,您可以将它与 Java、C++ 和 Python 一起使用。这是一个小费。

Why don't you use ProtocolBuffer to serialize. It is opensource and free plataform, you can use it with Java, C++ and Python. It's a tip.

清欢 2024-10-09 00:37:04

因为不可能在 dotnet 中序列化字典。我的解决方案是这样的:

输出:

**<Person>
  <FirstName>John</FirstName>
  <LastName>Doe</LastName>
  <Attributes>
    <PhoneNumber>12345</PhoneNumber>
    <StreetName>StackOverFlow Street</StreetName>
    <StreetNumber>51</StreetNumber>
  </Attributes>
</Person>**

核心代码

public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public Dictionary<string, string> Attributes { get; set; }
    }

    public class DictionarySerializer
    {
        private StringBuilder _sBuilder;
        private XmlWriterSettings _writerSettings;
        private XmlWriter w;

        public string WriteXml(Person personObject)
        {
            _sBuilder = new StringBuilder();
            _writerSettings = new XmlWriterSettings();

            _writerSettings.Indent = true;
            _writerSettings.OmitXmlDeclaration = true;
            w = XmlWriter.Create(_sBuilder, _writerSettings);

            //if you remove person properties any dictionary can be turned into XML.
            w.WriteStartElement("Person");           
            w.WriteElementString("FirstName", personObject.FirstName);
            w.WriteElementString("LastName", personObject.LastName);
            w.WriteStartElement("Attributes");

            foreach (var item in personObject.Attributes)
            {
                w.WriteElementString(item.Key, item.Value);
            }

            w.WriteEndElement();
            w.WriteEndElement();
            w.Close();

            return _sBuilder.ToString();
        }
    }

使用代码

 public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Person objP = new Person();
            objP.FirstName = "John";
            objP.LastName = "Doe";

            objP.Attributes = new Dictionary<string, string>();

            objP.Attributes.Add("PhoneNumber", "12345");
            objP.Attributes.Add("StreetName", "StackOverFlow Street");
            objP.Attributes.Add("StreetNumber", "51");

            DictionarySerializer ds = new DictionarySerializer();
            string val = ds.WriteXml(objP);
        }
    }

As its not possible to serialize a dictionary in dotnet. My Solution is this:

Output:

**<Person>
  <FirstName>John</FirstName>
  <LastName>Doe</LastName>
  <Attributes>
    <PhoneNumber>12345</PhoneNumber>
    <StreetName>StackOverFlow Street</StreetName>
    <StreetNumber>51</StreetNumber>
  </Attributes>
</Person>**

Core Code

public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public Dictionary<string, string> Attributes { get; set; }
    }

    public class DictionarySerializer
    {
        private StringBuilder _sBuilder;
        private XmlWriterSettings _writerSettings;
        private XmlWriter w;

        public string WriteXml(Person personObject)
        {
            _sBuilder = new StringBuilder();
            _writerSettings = new XmlWriterSettings();

            _writerSettings.Indent = true;
            _writerSettings.OmitXmlDeclaration = true;
            w = XmlWriter.Create(_sBuilder, _writerSettings);

            //if you remove person properties any dictionary can be turned into XML.
            w.WriteStartElement("Person");           
            w.WriteElementString("FirstName", personObject.FirstName);
            w.WriteElementString("LastName", personObject.LastName);
            w.WriteStartElement("Attributes");

            foreach (var item in personObject.Attributes)
            {
                w.WriteElementString(item.Key, item.Value);
            }

            w.WriteEndElement();
            w.WriteEndElement();
            w.Close();

            return _sBuilder.ToString();
        }
    }

Usage Code

 public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Person objP = new Person();
            objP.FirstName = "John";
            objP.LastName = "Doe";

            objP.Attributes = new Dictionary<string, string>();

            objP.Attributes.Add("PhoneNumber", "12345");
            objP.Attributes.Add("StreetName", "StackOverFlow Street");
            objP.Attributes.Add("StreetNumber", "51");

            DictionarySerializer ds = new DictionarySerializer();
            string val = ds.WriteXml(objP);
        }
    }
×眷恋的温暖 2024-10-09 00:37:03
        using System;
        using System.Collections.Generic;
        using System.Text;
        using System.Xml.Serialization;

        namespace CSharpSampleApplication.Data.CoreObjects
        {
            [XmlRoot("dictionary")]
            public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable
            {

                #region IXmlSerializable Members
                public System.Xml.Schema.XmlSchema GetSchema()
                {
                    return null;
                }

                public void ReadXml(System.Xml.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 != System.Xml.XmlNodeType.EndElement)
                    {
                        reader.ReadStartElement("item");
                        reader.ReadStartElement("key");
                        TKey key = (TKey)keySerializer.Deserialize(reader);
                        reader.ReadEndElement();
                        reader.ReadStartElement("value");
                        TValue value = (TValue)valueSerializer.Deserialize(reader);
                        reader.ReadEndElement();
                        this.Add(key, value);
                        reader.ReadEndElement();
                        reader.MoveToContent();
                    }
                    reader.ReadEndElement();

                }



                public void WriteXml(System.Xml.XmlWriter writer)
                {

                    XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
                    XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
                    foreach (TKey key in this.Keys)
                    {
                        writer.WriteStartElement("item");
                        writer.WriteStartElement("key");
                        keySerializer.Serialize(writer, key);
                        writer.WriteEndElement();
                        writer.WriteStartElement("value");
                        TValue value = this[key];
                        valueSerializer.Serialize(writer, value);
                        writer.WriteEndElement();
                        writer.WriteEndElement();
                    }
                }

                #endregion

            }
        }
        using System;
        using System.Collections.Generic;
        using System.Text;
        using System.Xml.Serialization;

        namespace CSharpSampleApplication.Data.CoreObjects
        {
            [XmlRoot("dictionary")]
            public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable
            {

                #region IXmlSerializable Members
                public System.Xml.Schema.XmlSchema GetSchema()
                {
                    return null;
                }

                public void ReadXml(System.Xml.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 != System.Xml.XmlNodeType.EndElement)
                    {
                        reader.ReadStartElement("item");
                        reader.ReadStartElement("key");
                        TKey key = (TKey)keySerializer.Deserialize(reader);
                        reader.ReadEndElement();
                        reader.ReadStartElement("value");
                        TValue value = (TValue)valueSerializer.Deserialize(reader);
                        reader.ReadEndElement();
                        this.Add(key, value);
                        reader.ReadEndElement();
                        reader.MoveToContent();
                    }
                    reader.ReadEndElement();

                }



                public void WriteXml(System.Xml.XmlWriter writer)
                {

                    XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
                    XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
                    foreach (TKey key in this.Keys)
                    {
                        writer.WriteStartElement("item");
                        writer.WriteStartElement("key");
                        keySerializer.Serialize(writer, key);
                        writer.WriteEndElement();
                        writer.WriteStartElement("value");
                        TValue value = this[key];
                        valueSerializer.Serialize(writer, value);
                        writer.WriteEndElement();
                        writer.WriteEndElement();
                    }
                }

                #endregion

            }
        }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文