XmlSerializer List Item Element Name

c#, xmlserializer

Solution

I don't think there is a way for you to control the name of the generated array elements.

If you can however wrap the `Persons` collection inside another class you will then have complete control over the generated output using `XmlArrayAttribute` and `XmlArrayItemAttribute`.

If you cannot create this new class you can resort to implementing `IXmlSerializable`, but this is much more complex.

An example for the first alternative follows:

[XmlRoot("Context")]
public class Context
{
    public Context() { this.Persons = new Persons(); }

    [XmlArray("Persons")]
    [XmlArrayItem("Person")]
    public Persons Persons { get; set; }
}

public class Persons : List<Human> { }

public class Human
{
    public Human() { }
    public Human(string name) { Name = name; }
    public string Name { get; set; }
}

class Program
{
    public static void Main(string[] args)
    {
        Context ctx = new Context();
        ctx.Persons.Add(new Human("john"));
        ctx.Persons.Add(new Human("jane"));

        var writer = new StringWriter();
        new XmlSerializer(typeof(Context)).Serialize(writer, ctx);

        Console.WriteLine(writer.ToString());
    }
}

Problem

I have a class `PersonList` ``` [XmlRoot("Persons")] PersonList : List<Human> ``` when I serialize this to XML, by default it will produce something like this: ``` <Persons> <Human>...</Human> <Human>...</Human> </Persons> ``` My question is what needs to be done in order to change element `Human` to `Person` in the output? so the output would be : ``` <Persons> <Person>...</Person> <Person>...</Person> </Persons> ``` and, how to deserialize the above XML to the `PersonList` class object? Per Nick's advice, Here is my testing code: ``` [XmlRoot("Persons")] public class Persons : List<Human> { } [XmlRoot("Person")] public class Human { public Human() { } public Human(string name) { Name = name; } [XmlElement("Name")] public string Name { get; set; } } void TestXmlSerialize() { Persons personList = new Persons(); personList.Add(new Human("John")); personList.Add(new Human("Peter")); try { using (StringWriter writer = new StringWriter()) { XmlSerializer serializer = new XmlSerializer(typeof(Persons)); XmlWriterSettings settings = new XmlWriterSettings(); settings.OmitXmlDeclaration = true; XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces(); namespaces.Add(string.Empty, string.Empty); XmlWriter xmlWriter = XmlWriter.Create(writer, settings); serializer.Serialize(xmlWriter, personList, namespaces); Console.Out.WriteLine(writer.ToString()); } } catch (Exception e) { Console.Out.WriteLine( e.ToString()); } } ``` The output of the testing code is: ``` <Persons> <Human> <Name>John</Name> </Human> <Human> <Name>Peter</Name> </Human> </Persons> ``` As the output shows, the `[XmlRoot("Person")]` on `Human` does not change the tag to `Person` from `Human`.

Original source

Related problems