kaa*_*len 7 .net c# xml xml-serialization
想要将我的数据序列化为:
<?xml version="1.0" encoding="ibm850"?>
<Batch Name="Test batch">
   <ExecuteCommand Command="..." />
   <WaitCommand Seconds="5" />
</Batch>
Run Code Online (Sandbox Code Playgroud)
但相反,我得到这个(注意包装命令元素)
<?xml version="1.0" encoding="ibm850"?>
<Batch Name="Test batch">
  <Commands><!-- I want to get rid of thiw wrapper Commands element and just  -->
    <ExecuteCommand Command="..." />
    <WaitCommand Seconds="5" />
  </Commands>
</Batch>
Run Code Online (Sandbox Code Playgroud)
以下是用于生成此代码的示例代码:
public class BaseCommand //base class
{
    [XmlAttribute]
    public string Result { get; set; }
}
public class ExecuteCommand : BaseCommand
{
    [XmlAttribute]
    public string Command { get; set; }
}
public class WaitCommand : BaseCommand
{
    [XmlAttribute]
    public int Seconds { get; set; }
}
public class Batch
{
    [XmlAttribute]
    public string Name { get; set; }
    private List<BaseCommand> _commands = new List<BaseCommand>();
    [XmlArrayItem(typeof(ExecuteCommand))]
    [XmlArrayItem(typeof(WaitCommand))]
    public List<BaseCommand> Commands
    {
        get
        {
            return _commands;
        }
        set
        {
            _commands = value;
        }
    }
    public static void Main()
    {
        XmlSerializer serializer = new XmlSerializer(typeof(Batch));
        Batch b = new Batch();
        b.Name = "Test batch";
        b.Commands.Add(new ExecuteCommand() { Command = "..." });
        b.Commands.Add(new WaitCommand() { Seconds = 5 });
        serializer.Serialize(Console.Out, b);
        Console.Read();
    }
}
Run Code Online (Sandbox Code Playgroud)
我搜索并阅读了关于这个主题的大量文章.它们似乎都提供了使用单个类型序列化集合的解决方案(不使用继承).我使用继承,似乎没有任何工作.不幸的是,由于遗留支持,我必须输出精确的XML文档
这是很久以前的事了,但我最终还是自己想出来了.
解决方案是将每个受支持的派生类型的[XmlElement]属性添加到集合属性
private List<BaseCommand> _commands = new List<BaseCommand>();
[XmlElement(typeof(ExecuteCommand))]
[XmlElement(typeof(WaitCommand))]
public List<BaseCommand> Commands
{
    get
    {
        return _commands;
    }
    set
    {
        _commands = value;
    }
}
Run Code Online (Sandbox Code Playgroud)