Reputation: 2128
I have an array whose indices map back to Enum
values. I would like to use the C# Xml Serialization libraries to serialize this array. However, I would like each Xml node to say the name of the Enum type that it represents. How can I do this?
Example:
public class NumberOfEmployees
{
public enum EmployeeType { Lawyer, Doctor, Engineer };
public int[] NumEmployees { get; set; }
// Constructor initializes array to size of "EmployeeType"
public NumberOfEmployees()
{
int size = Enum.GetValues(typeof(EmployeeType)).Length;
this.NumEmployees = new int[size];
}
}
Main()
{
NumberOfEmployees numEmployees = new NumberOfEmployees();
// Add doctors, lawyers, engineers, etc...
// numEmployees.NumEmployees[(int)NumberOfEmployees.Lawyer] = 3;
// numEmployees.NumEmployees[(int)NumberOfEmployees.Doctor] = 2;
// numEmployees.NumEmployees[(int)NumberOfEmployees.Engineer] = 1;
// Serialize to "file"
FileStream fs = new FileStream(file, FileMode.OpenOrCreate);
XmlSerializer xml = new XmlSerializer(typeof(NumberOfEmployees));
xml.Serialize(fs, numEmployees);
fs.Close();
}
The end result is xml that looks something like this:
<NumEmployees>
<int>3</int>
<int>2</int>
<int>1</int>
</NumEmployees>
But what I want is:
<NumEmployees>
<Lawyer>3</Lawyer>
<Doctor>2</Doctor>
<Engineer>1</Engineer>
</NumEmployees>
I can not store each number separately -- it must be an array.
Thanks.
Upvotes: 1
Views: 459
Reputation: 7757
You can implement the IXmlSerializable interface to completely customize serialization with XmlSerializer. Something similar to the following:
public class NumberOfEmployees : IXmlSerializable
{
public int[] NumEmployees { get; set; }
// Constructor initializes array to size of "EmployeeType"
public NumberOfEmployees()
{
int size = Enum.GetValues(typeof(EmployeeType)).Length;
this.NumEmployees = new int[size];
}
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
reader.ReadStartElement();
NumEmployees[(int)EmployeeType.Lawyer] = int.Parse(reader.ReadElementString("Lawyer"));
NumEmployees[(int)EmployeeType.Doctor] = int.Parse(reader.ReadElementString("Doctor"));
NumEmployees[(int)EmployeeType.Engineer] = int.Parse(reader.ReadElementString("Engineer"));
reader.ReadEndElement();
}
public void WriteXml(XmlWriter writer)
{
writer.WriteElementString("Lawyer", NumEmployees[(int)EmployeeType.Lawyer].ToString());
writer.WriteElementString("Doctor", NumEmployees[(int)EmployeeType.Doctor].ToString());
writer.WriteElementString("Engineer", NumEmployees[(int)EmployeeType.Engineer].ToString());
}
}
After you've done all that it might seem pointless to still use XmlSerializer
since your class is handling all the work of serialization. It still makes sense, however, if the NumberOfEmployees
is part of a larger XML structure (which I assume it is).
Also note that the code doesn't do any validation, because this is a simple example. So all three array elements will be expected to exist when the class is serialized, and all three XML elements will be expected to exist when it is deserialized.
More info on the IXmlSerializable
interface is available here:
http://msdn.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable.aspx
Upvotes: 4