0

我有一个 xml 文件,其中包含一个看起来像这样的集合

<AbstractCollection>
    <ConcreteA name="Bob" age="4"/>
    <ConcreteB name="Tree" size="1" />
</AbstractCollection>

我知道如果我使用一个具体的集合——即两个元素是相同的类型——在 C# 中使用标准的 XML 反序列化会很容易。不同的类型似乎使它变得更加困难。

有没有办法使用简单的 xml 反序列化来解决这个问题,还是我必须自己实现反序列化?

[为清楚起见添加] 我应该补充一点,xml 已经存在并且我无法更改它。我在 xml 中接收采用上述形式的消息。一个更具体的例子是:

<Actions>
    <Walked name="Bob" distance="4"/>
    <Cycled name="Jane" gear="3rd" />
</Actions>

我想要结束的是一个“循环”和一个“步行”对象。哦,为了让它更有趣,顺序很重要。

另外,我尝试在代码中使用 XmlInclude 属性,但是通过在序列化时更改 xml 来工作(当然,除非我一直在使用错误)。

4

1 回答 1

1

所以我找到了解决方案,感谢这个答案

关键是用来XmlElementAttribute改变不同类的序列化方式。

唯一奇怪的部分是我发现我必须为列表创建一个包装类,否则 Cycled 和 Walked 元素不会包装在根元素中。

我知道命名空间的东西还在,但我可以处理——获取派生类的问题已经解决了!

感谢所有参与的人。

[Serializable]
public class Actions
{
    [XmlElementAttribute("Walked", typeof(WalkedAction))]
    [XmlElementAttribute("Cycled", typeof(CycledAction))]
    public List<Action> ActionList { get; set; }
}
[Serializable]
public abstract class Action
{
    [XmlAttribute]
    public string Name { get; set; }
}

[Serializable]
public class WalkedAction : Action
{
    [XmlAttribute]
    public int Distance { get; set; }
}

[Serializable]
public class CycledAction : Action
{
    [XmlAttribute]
    public string Gear { get; set; }
}


public class Program
{
    public static void Main(string[] args)
    {
        var actionList = new Actions();
        actionList.ActionList = new List<Action>();
        actionList.ActionList.Add(new WalkedAction { Name = "Bob", Distance = 4 });
        actionList.ActionList.Add(new CycledAction { Name = "Jane", Gear = "3rd" });

        var ser = new XmlSerializer(typeof(Actions));

        TextWriter w = new StringWriter();
        ser.Serialize(w, actionList);

        TextReader r = new StringReader(w.ToString());
        Actions result = (Actions) ser.Deserialize(r);
    }
}
于 2013-03-26T11:51:31.170 回答