I am trying to serailize an Object into XML. Below is the XML format which I need.
Key1
<
You either need to make Parameter contain a list of the key values (by the way .net has several collections that do this for you such as Dictionary) e.g:
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
}
Or in parameters just make it a list of key values or a dictionary:
public class Parameters<K,V>{
public Dictionary<K,V> Parameters {get; set;}
public Parameters(){
Parameters = new Dictionary<K,V>();
}
}
The second option is obviously the best one as the first is just re-inventing the .net Dictionary. There doesn't seem to be any benefit to the first.
This is bread and butter stuff so if you don't really understand arrays and .net collections you should familiarize yourself with this area. Searching on stack overflow will give you all you need.
You can use XmlElementAttribute.ElementName property to name the Parameters Dictionary as you like and it should produce the results you want although I would question why inside the parameters node you only want one parameter node?
From the point of view of XmlSerializer
, the <parameter>
element of your XML isn't a list of key/value pair classes, because there's no nesting of each pair in some containing element. Instead it's a polymorphic list, where each entry can be an element of type <key>
or of type <value>
. So the easiest way to handle this may be to use the built-in functionality of the serializer for handling lists of polymorphic types as follows:
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;
}
}
}
}
The [XmlArrayItem("someTypeName", typeof(SomeType))] decorations tell the serializer that array elements of type SomeType
(in this case ParameterKey<string>
and ParameterValue<string>
) are to be serialized with element name "someTypeName"
("key"
and "value"
, respectively.)