I have a set of .net classes that I currently serialize and use with a bunch of other code, so the format of that xml is relatively fixed (format #1). I need to generate xml in another format (format #2) that's a pretty similar structure but not exactly the same, and am wondering the best approach for this.
For example, say these are my classes:
public class Resource
{
public string Name { get; set; }
public string Description { get; set; }
public string AnotherField { get; set; }
public string AnotherField2 { get; set; }
public Address Address1 { get; set; }
public Address Address2 { get; set; }
public Settings Settings { get; set; }
}
public class Address
{
public string Line1 { get; set; }
public string Line2 { get; set; }
public string City { get; set; }
}
// This class has custom serialization because it's sort-of a dictionary.
// (Maybe that's no longer needed but it seemed necessary back in .net 2.0).
public class Settings : IXmlSerializable
{
public string GetSetting(string settingName) { ... }
public string SetSetting(string settingName, string value) { ... }
public XmlSchema GetSchema() { return null; }
public void ReadXml(XmlReader reader)
{
// ... reads nested <Setting> elements and calls SetSetting() appropriately
}
public void WriteXml(XmlWriter writer)
{
// ... writes nested <Setting> elements
}
}
I normally use standard XmlSerialization and it produces great XML (format #1). Something like:
<Resource>
<Name>The big one</Name>
<Description>This is a really big resource</Description>
<AnotherField1>ADVMW391</AnotherField1>
<AnotherField2>green</AnotherField2>
<Address1>
<Line1>1 Park Lane</Line1>
<Line2>Mayfair</Line2>
<City>London</City>
</Address1>
<Address2>
<Line1>11 Pentonville Rd</Line1>
<Line2>Islington</Line2>
<City>London</City>
</Address2>
<Settings>
<Setting>
<Name>Height</Name>
<Value>12.4</Value>
</Setting>
<Setting>
<Name>Depth</Name>
<Value>14.1028</Value>
</Setting>
</Settings>
</Resource>
The new XML I want to generate (format #2) looks like the current XML, except:
Instead of field
AnotherField
andAnotherField2
, these should now be represented as Settings. ie as if SetSetting() was called twice before serializing, so the values appear as new elements within .Instead of fields
Address1
andAddress2
, these should be represented as an element containing two elements. The elements should have an extra attribute or two, e.g. Position and AddressType.
e.g.
<Resource>
<Name>The big one</Name>
<Description>This is a really big resource</Description>
<Addresses>
<Address>
<Line1>1 Park Lane</Line1>
<Line2>Mayfair</Line2>
<City>London</City>
<Position>1</Position>
<AddressType>Postal</AddressType>
</Address>
<Address>
<Line1>11 Pentonville Rd</Line1>
<Line2>Islington</Line2>
<City>London</City>
<Position>2</Position>
<AddressType>Postal</AddressType>
</Address>
</Addresses>
<Settings>
<Setting>
<Name>Height</Name>
<Value>12.4</Value>
</Setting>
<Setting>
<Name>Depth</Name>
<Value>14.1028</Value>
</Setting>
<Setting>
<Name>AnotherField</Name>
<Value>ADVMW391</Value>
</Setting>
<Setting>
<Name>AnotherField2</Name>
<Value>green</Value>
</Setting>
</Settings>
</Resource>
Can I use XmlAttributeOverrides to control serialization in this way? Otherwise how should I approach it?
Bear in mind that my real classes have at least 10 times the number of fields, and there are some nested classes where I'm completely happy with the default serialization, so I'd like to avoid too much manual serialization code.
Possible Options
I can see these options:
- Maybe it's possible to use overrides to control serialization of just the attributes I care about?
- Custom serialization of the Resource class for format #2, calling the default serialization of nested classes where appropriate. Not sure how to deal with Settings as I effectively want to add settings, serialize using default, then remove the added settings.
- Create xml using default serialization, then manipulate the XML to make the changes I need. (ick!).
Another slight complication is that Resource
from my example above actually has two subtypes, each with a couple of extra fields. The default serialization handles this nicely. Any new method would need to deal with serializing these subtypes too. This means I'm not keen on a solution that involves me making different subtypes purely for serialization purposes.