我有一个我正在尝试序列化为 XML 的对象。这个对象内部是一个泛型类型(抽象类)的列表。此列表中的每个项目都可以是不同的类,但都继承自抽象基类:
public abstract class animal
{
public string type { get; set; }
}
public class cat:animal
{
public string size { get; set; }
public string furColor { get; set; }
}
public class fish:animal
{
public string size { get; set; }
public string scaleColor { get; set; }
}
当我序列化列表时,我希望它看起来像这样:
<animal type="cat">
<size>medium</size>
<furColor>black</furColor>
</animal>
<animal type="fish">
<size>small</size>
<scaleColor>silver</scaleColor>
</animal>
我尝试了简单的解决方案:
[XmlElement("Animal")]
public List<animal> Animals { get; set; }
但它会引发错误,因为它不期望对象类型“cat”。将 [XmlInclude] 标记添加到基类、派生类或整个包含类(我们称之为 zoo)对此没有帮助。
我可以将 typeof 指定用于单个类:
[XmlElement("Animal", typeof(cat))]
public List<animal> Animals { get; set; }
只要我只使用猫,它就可以正常工作,就像我想要的那样。同样,当我在混合物中添加一条鱼时,它会因同样的错误而爆炸(不期望有鱼)。
我可以添加多个 typeof 属性:
[XmlElement("Animal")]
[XmlElementAttribute(typeof(cat))]
[XmlElementAttribute(typeof(fish))]
public List<animal> Animals { get; set; }
这会编译,但会忽略元素名称,并将对象分别序列化为<cat> </cat>
和<fish> </fish>
,这是不可接受的。
我什至尝试添加多个 [XmlElement] 标签:
[XmlElement("Animal", typeof(cat))]
[XmlElement("Animal", typeof(fish))]
public List<animal> Animals { get; set; }
这个抛出了一个不同的异常,这一次对象“cat”和“fish”都在同一范围内使用“Animal”类型。
谁能想到解决这个问题的方法?
更新经过一番挖掘,我发现这篇 SO 帖子建议将命名空间添加到基类中:
[XmlRoot(Namespace="myNamespace")]
[XmlInclude(typeof(cat))]
[XmlInclude(typeof(fish))]
public abstract class animal
序列化它会产生以下结果:
<animal xsi:type="cat" type="cat">
...
</animal>
<animal xsi:type="fish" type="fish">
...
</animal>
其中xsi:type="cat"是指类的名称,而type="cat"是指在基类中创建的类型属性(参见最上面的示例)。这与我需要的非常接近,我担心我可能只是在这里缺乏经验,但是有没有办法摆脱 xsi:type 属性列表?