Xml序列化:使用元素的基类名称序列化从同一基类派生的自定义类的列表
本文关键字:序列化 基类 自定义 列表 派生 元素 Xml | 更新日期: 2023-09-27 18:02:14
编辑
我的假设错了。我回答自己,解释出了什么问题,以及我真正需要什么。
我在序列化不同自定义类的列表时遇到问题。它们中的每一个都继承自同一个基类,Xml文件应该显示具有基类名称的元素。
这就是我想要的Xml文件的样子:
<TestDataMap>
<DataMap>
<Item Key="BoolStatus">True</Item>
<Item Key="IntStatus">77</Item>
</DataMap>
</TestDataMap>
我的实际代码是由一个基类组成的:
public class BaseItem
{
[XmlAttribute("Key")]
public string Key { get; set; }
[XmlText]
public string Value { get; set; }
}
和多个自定义类,例如:
[XmlType("ItemBool")]
public class ItemBool : BaseItem
{
public ItemBool()
{
base.Key = string.Empty;
ValueBool = false;
}
[XmlIgnore]
public bool ValueBool
{
get { return bool.Parse(base.Value); }
set { base.Value = value.ToString(); }
}
}
[XmlType("ItemInt")]
public class ItemInt : BaseItem
{
public ItemInt()
{
base.Key = string.Empty;
ValueInt = int.MinValue;
}
[XmlIgnore]
public int ValueInt
{
get { return int.Parse(base.Value); }
set { base.Value = value.ToString(); }
}
}
我需要将所有这些自定义类序列化为基类的列表,因此我完成了以下操作:
[XmlRoot("TestDataMap")]
public class TestDataMap
{
public TestDataMap()
{
DataMap = new List<BaseItem>();
}
// If I use the following I've got serialization exception...
//[XmlArrayItem("Item", typeof(ItemBool))]
//[XmlArrayItem("Item", typeof(ItemInt))]
[XmlArray("DataMap")]
[XmlArrayItem("Item", typeof(BaseItem))]
public List<BaseItem> DataMap { get; set; }
}
为了测试序列化,我使用了一个按钮事件:
private void button1_Click(object sender, EventArgs e)
{
TestDataMap testDataMap = new TestDataMap();
ItemBool itemBool = new ItemBool() { Key = "BoolStatus", ValueBool = true };
ItemInt itemInt = new ItemInt() { Key = "IntStatus", ValueInt = 77 };
testDataMap.DataMap.Add(itemBool);
testDataMap.DataMap.Add(itemInt);
TextWriter writer = new StreamWriter(@"c:'TempTest.xml");
Type[] dataMapTypes = new Type[] { typeof(ItemBool), typeof(ItemInt) };
XmlSerializer serializer = new XmlSerializer(typeof(TestDataMap), dataMapTypes);
serializer.Serialize(writer, testDataMap);
writer.Close();
}
但我得到了这样的输出:
<TestDataMap>
<DataMap>
<Item Key="BoolStatus" xsi:type="ItemBool">True</Item>
<Item Key="IntStatus" xsi:type="ItemInt">77</Item>
</DataMap>
</TestDataMap>
包含我不想显示的xsi:type
信息。。。我的代码出了什么问题?关于我必须更改什么才能获得问题开始时发布的Xml结构,有什么建议吗?
当我问这个问题时,我过于关注输出xml文件的美学结果,而不关心要点:自定义类的xml序列化和随后的反序列化。即使我能够像最初发布的那样准确地获得xml元素,那么在反序列化过程中我也会遇到问题:在没有任何其他细节的情况下,反序列化程序如何从通用<Item>
元素列表中知道哪个是<ItemBool>
,哪个是<ItemInt>
?
考虑到这一点,我明白我所要求的不是我所需要的,也不是进行xml序列化的正确方法。
因此,我将上面发布的TestDataMap
类更改为以下内容:
[XmlRoot("TestDataMap")]
public class TestDataMap
{
public TestDataMap()
{
DataMap = new List<BaseItem>();
}
[XmlArray("DataMap")]
[XmlArrayItem("ItemBool", typeof("ItemBool"))]
[XmlArrayItem("ItemInt", typeof("ItemInt"))]
public List<BaseItem> DataMap { get; set; }
}
要获得此xml输出:
<TestDataMap>
<DataMap>
<ItemBool Key="BoolStatus">True</ItemBool>
<ItemInt Key="IntStatus">77</ItemInt>
</DataMap>
</TestDataMap>
通过这种方式,反序列化器可以清楚地了解它必须如何反序列化每种类型的<Item>
元素。