【问题标题】:I'm not sure how to best organize data so that it can be serialized by the XML Serializer我不确定如何最好地组织数据,以便它可以被 XML 序列化器序列化
【发布时间】:2014-04-24 19:30:10
【问题描述】:

我有一个 Setting 结构,它包含一个 namedescriptiontype 作为strings,以及一个 value 作为Object。现在有一个包含一组设置的类。此类基本上充当创建对象的工厂,然后该对象应包含这些 settings 分配给键的列表/数组。我最好的办法是创建一个这样的字典:Dictionary<KeyCode, Setting[]> 甚至更好的Dictionary<KeyCode, Dictionary<string, Settings>>(通过设置名称组织),但不幸的是字典不能通过 XML 序列化。现在我有两个问题:

XML 是否可以序列化和反序列化 Object 类型的对象(它们只包含像 float 和 bool 这样的值类型)?

如何将设置列表分配给键,同时保持 xml 的可序列性?

【问题讨论】:

  • struct 似乎不适合这种类型。
  • 也许不使用XmlSerializer,而是自己序列化,也许通过LINQ to XML?
  • 我刚刚使用 DataContractSerializer 进行了快速测试,并且能够序列化字典 没有任何特殊(人只是两个字符串)

标签: c# xml object serialization dictionary


【解决方案1】:

有一个 IXmlSerializable 字典。这取自Paul Welter's Weblog - XML Serializable Generic Dictionary

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

[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
}

对于第二个问题,您可以使用 XmlElement 标记告诉 Object 类型属性它接受的可能值:

public class MyClass
{
   [XmlElement("a", Type = typeof(int))]
   [XmlElement("b", Type = typeof(string))]
   [XmlElement("c", Type = typeof(float))]
    public object Value { get; set; }
}

xml 会根据类型生成每个值:

<MyClass>
  <b>abc</b>
</MyClass>

<MyClass>
  <a>123</a>
</MyClass>

<MyClass>
  <c>45.7</c>
</MyClass>

【讨论】:

  • 谢谢,a、b、c 到底是什么意思?
  • 它们是标签将接收的名称。
  • hmm,所以如果值是一个int,标签将是1 ?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-02
  • 2019-06-20
  • 2010-09-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多