使用父标记序列化基类的List <t> </t>

时间:2012-05-09 21:38:22

标签: c# .net serialization

我似乎能够在网上找到那些试图避免这种行为的人,但我似乎无法得到我想要的行为。

我有一个动物列表,我想为每种动物类型使用不同的标签序列化它们(而不是带有附加属性的默认beahviour)

要获得此行为,我正在使用以下代码

    [XmlElementAttribute(Order = 4)]
    [XmlElement("Frog", typeof(Frog))]
    [XmlElement("Cat", typeof(Cat))]
    [XmlElement("Dog", typeof(Dog))]
    public List<Animal> lines = new List<Animal>();

哪个效果很好,除了它使列表变得平坦,如果xml输出更像,我更喜欢它    <animals> <Dog>Bob</Dog> <Cat>Fred</Cat> <Dog>Mike</Dog> </animals> 保留<animals>标记

2 个答案:

答案 0 :(得分:2)

更改[XmlElementAttribute(Order = 4)]

[XmlArrayAttribute(Order=4)]

您还可以在属性中指定ElementName参数,该参数将是根名称,即:[XmlArrayAttribute(Order=4, ElementName="animals")]

* 注意:Order = 4特定于此情况。你通常不需要它。 *

编辑:(感谢OP评论):

您还必须更改属于列表的对象类的属性,从[XmlElement]更改为[XmlArrayItem] (MSDN doc here),如下所示:

[XmlArrayItem("Frog", typeof(Frog))]
[XmlArrayItem("Cat", typeof(Cat))]
[XmlArrayItem("Dog", typeof(Dog))]

答案 1 :(得分:0)

您始终可以将列表包装在自己的类中,并且您将获得所需的XML:

public class StackOverflow_10524470
{
    public class Animal
    {
        [XmlText]
        public string Name { get; set; }
    }
    public class Dog : Animal { }
    public class Cat : Animal { }
    public class Frog : Animal { }
    public class Root
    {
        [XmlElementAttribute(Order = 4, ElementName = "animals")]
        public Animals animals;
    }
    public class Animals
    {
        [XmlElementAttribute(Order = 4)]
        [XmlElement("Frog", typeof(Frog))]
        [XmlElement("Cat", typeof(Cat))]
        [XmlElement("Dog", typeof(Dog))]
        public List<Animal> lines = new List<Animal>();
    }
    public static void Test()
    {
        MemoryStream ms = new MemoryStream();
        XmlSerializer xs = new XmlSerializer(typeof(Root));
        Root root = new Root
        {
            animals = new Animals
            {
                lines = new List<Animal> 
                { 
                    new Dog { Name = "Fido" },
                    new Cat { Name = "Fluffy" },
                    new Frog { Name = "Singer" },
                }
            }
        };
        xs.Serialize(ms, root);
        Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
    }
}