Suppose I have an XML-serializable class called Song:
[Serializable] class Song { public string Artist; public string SongTitle; }
In order to save space (and also semi-obfuscate the XML file), I decide to rename the xml elements:
[XmlRoot("g")] class Song { [XmlElement("a")] public string Artist; [XmlElement("s")] public string SongTitle; }
This will produce XML output like this:
<Song> <a>Britney Spears</a> <s>I Did It Again</s> </Song>
I want to rename/remap the name of the class/object as well. Say, in the above example, I wish to rename the class Song to g. So that the resultant xml should look like this:
<g> <a>Britney Spears</a> <s>I Did It Again</s> </g>
Is it possible to rename class-names via xml-attributes?
I don't wish to create/traverse the DOM manually, so I was wondering if it could be achieved via a decorator.
Thanks in advance!
UPDATE: Oops! This time I really did it again! Forgot to mention - I'm actually serializing a list of Song objects in the XML.
Here's the serialization code:
public static bool SaveSongs(List<Song> songs) { XmlSerializer serializer = new XmlSerializer(typeof(List<Song>)); using (TextWriter textWriter = new StreamWriter("filename")) { serializer.Serialize(textWriter, songs); } }
And here's the XML output:
<?xml version="1.0" encoding="utf-8"?> <ArrayOfSong> <Song> <a>Britney Spears</a> <s>Oops! I Did It Again</s> </Song> <Song> <a>Rihanna</a> <s>A Girl Like Me</s> </Song> </ArrayOfSong>
Apparently, the XmlRoot() attribute doesn't rename the object in a list context.
Am I missing something?
XmlRoot only works with XML root nodes as per the documentation (and what you would expect, given its name includes root)!
I was unable to get any of the other answers to work so kept digging...
Instead I found that the XmlTypeAttribute (i.e. [XmlType]
) and its TypeName property do a similar job for non-root classes/objects.
e.g.
[XmlType(TypeName="g")] class Song { public string Artist; public string SongTitle; }
Assuming you apply it to the other classes e.g.:
[XmlType(TypeName="a")] class Artist { ..... } [XmlType(TypeName="s")] class SongTitle { ..... }
This will output the following exactly as required in the question:
<g> <a>Britney Spears</a> <s>I Did It Again</s> </g>
I have used this in several production projects and found no problems with it.
Checkout the XmlRoot attribute.
Documentation can be found here: http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlrootattribute(v=VS.90).aspx
[XmlRoot(Namespace = "www.contoso.com", ElementName = "MyGroupName", DataType = "string", IsNullable=true)] public class Group
UPDATE: Just tried and it works perfectly on VS 2008. This code:
[XmlRoot(ElementName = "sgr")] public class SongGroup { public SongGroup() { this.Songs = new List<Song>(); } [XmlElement(ElementName = "sgs")] public List<Song> Songs { get; set; } } [XmlRoot(ElementName = "g")] public class Song { [XmlElement("a")] public string Artist { get; set; } [XmlElement("s")] public string SongTitle { get; set; } }
Outputs:
<?xml version="1.0" encoding="utf-8"?> <sgr xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www .w3.org/2001/XMLSchema"> <sgs> <a>A1</a> <s>S1</s> </sgs> <sgs> <a>A2</a> <s>S2</s> </sgs> </sgr>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With