我有一个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>
我最终想要的是“Cycled”和“Walked”对象。哦,为了让它更有趣,订单很重要。
另外,我已经尝试在代码中使用XmlInclude属性,但是在序列化时通过更改xml起作用(除非我当然错误地使用它)。
答案 0 :(得分:1)
所以我找到了解决方案,感谢this answer。
关键是使用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);
}
}