将KeyValuePair列表序列化为XML

时间:2015-05-25 16:51:15

标签: c# xml serialization

我正在尝试将Object安装到XML中。以下是我需要的XML格式。

<parameters>
  <parameter>
    <key>Key1</key>
    <value>Value1</value>
    <key>Key2</key>
    <value>Value2</value>
    <key>Key3</key>
    <value>value3</value>
  </parameter>
</parameters>

以下是我创建的模型

[Serializable]
[XmlType("parameters")]
public class parameters
{
    public List<parameter<string,string>> parameter { get; set; }
}

[Serializable]
[XmlType("parameter")]
public class parameter<K,V>
{
    public K key { get; set; }
    public V value { get; set; }

    public parameter() { }

    public parameter(K key, V value)
    {
        this.key = key;
        this.value = value;
    }
}

当我尝试序列化为XML时,我得到以下格式

<parameters>
  <parameter>
    <parameter>
      <key>Key1</key>
      <value>Value1</value>
    </parameter>
    <parameter>
      <key>Key2</key>
      <value>Value2</value>
    </parameter>
    <parameter>
      <key>Key3</key>
      <value>Value3</value>
    </parameter>
  </parameter>
</parameters>

请帮我解决这个问题。

2 个答案:

答案 0 :(得分:1)

tabChangesFocus的角度来看,XML的XmlSerializer元素不是键/值对类的列表,因为在某些包含元素中没有每对的嵌套。相反,它是polymorphic list,其中每个条目可以是<parameter>类型或<key>类型的元素。因此,处理此问题的最简单方法可能是使用序列化程序的内置功能来处理多态类型列表,如下所示:

<value>

[XmlArrayItem("someTypeName", typeof(SomeType))]装饰告诉序列化程序类型为public abstract class ParameterKeyOrValue<T> { [XmlText] public T Text { get; set; } } public sealed class ParameterKey<T> : ParameterKeyOrValue<T> { } public sealed class ParameterValue<T> : ParameterKeyOrValue<T> { } [Serializable] [XmlType("parameters")] public class parameters { [XmlIgnore] public List<parameter<string, string>> parameter { get; set; } [XmlArray("parameter")] [XmlArrayItem("key", typeof(ParameterKey<string>))] [XmlArrayItem("value", typeof(ParameterValue<string>))] [Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)] public ParameterKeyOrValue<string>[] XmlParameters { get { if (parameter == null) return null; return parameter.SelectMany(p => new ParameterKeyOrValue<string>[] { new ParameterKey<string> { Text = p.key }, new ParameterValue<string> { Text = p.value } }).ToArray(); } set { if (value == null) parameter = null; else { if (value.Length % 2 != 0) throw new ArgumentException("Unequal number of keys and values"); var newParameters = value.OfType<ParameterKey<string>>().Zip(value.OfType<ParameterValue<string>>(), (k, v) => new parameter<string, string>(k.Text, v.Text)).ToList(); // Make sure we got an equal number of keys and values. if (newParameters.Count != value.Length / 2) throw new ArgumentException("Unequal number of keys and values"); parameter = newParameters; } } } } 的数组元素(在本例中为SomeTypeParameterKey<string>)将使用元素名称{{1}进行序列化(分别为ParameterValue<string>"someTypeName"。)

答案 1 :(得分:0)

您需要使参数包含键值列表(顺便说一句.net有几个为您执行此操作的集合,例如Dictionary),例如:

public class Parameter<K,V>{
  public Dictionary<K,V> Values {get; set;}

  public Parameter()
  {
     Values = new Dictionary<K,V>();
  }

  public void AddParameter(K key, V value)
  {
     Values.Add(key,value);
  }

  ...Other access methods here
}

或者在参数中只需将其作为键值列表或字典:

public class Parameters<K,V>{

   public Dictionary<K,V> Parameters {get; set;}

   public Parameters(){
       Parameters = new Dictionary<K,V>();
   }
}

第二个选项显然是最好的选择,因为第一个选项只是重新发明.net字典。对第一个似乎没什么好处。

这是面包和黄油的东西,所以如果你真的不了解数组和.net集合,你应该熟悉这个领域。搜索堆栈溢出将为您提供所需的一切。

你可以使用XmlElementAttribute.ElementName属性来命名参数字典,它应该产生你想要的结果,虽然我会质疑为什么在参数节点里你只需要一个参数节点?