How can I rename class-names via Xml attributes? How can I rename class-names via Xml attributes? xml xml

How can I rename class-names via Xml attributes?


Solution: Use [XmlType(TypeName="g")]

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 this is the root element of the document, you can use [XmlRoot("g")].


Here is my updated response based on your clarification. The degree of control you are asking for is not possible without a wrapping class. This example uses a SongGroup class to wrap the list so that you can give alternate names to the items within.

using System;using System.Collections.Generic;using System.IO;using System.Xml.Serialization;public class SongGroup{    public SongGroup()    {        this.Songs = new List<Song>();    }    [XmlArrayItem("g", typeof(Song))]    public List<Song> Songs { get; set; }}public class Song {     public Song()    {    }    [XmlElement("a")]     public string Artist { get; set; }    [XmlElement("s")]    public string SongTitle { get; set; }} internal class Test{    private static void Main()    {        XmlSerializer serializer = new XmlSerializer(typeof(SongGroup));        SongGroup group = new SongGroup();        group.Songs.Add(new Song() { Artist = "A1", SongTitle = "S1" });        group.Songs.Add(new Song() { Artist = "A2", SongTitle = "S2" });        using (Stream stream = new MemoryStream())        using (StreamWriter writer = new StreamWriter(stream))        {            serializer.Serialize(writer, group);            stream.Seek(0, SeekOrigin.Begin);            using (StreamReader reader = new StreamReader(stream))            {                Console.WriteLine(reader.ReadToEnd());            }        }    }}

This has the side effect of generating one more inner element representing the list itself. On my system, the output looks like this:

<?xml version="1.0" encoding="utf-8"?><SongGroup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">  <Songs>    <g>      <a>A1</a>      <s>S1</s>    </g>    <g>      <a>A2</a>      <s>S2</s>    </g>  </Songs></SongGroup>