我有一系列水果对象,其中一些是橘子,其中一些是苹果 我想将它们序列化为一个看起来像的列表:
<Fruits>
<AppleFruit>
<IsRotten>true</IsRotten>
<FellFarFromTree>false</FellFarFromTree>
</AppleFruit>
<OrangeFruit>
<IsRotten>false</IsRotten>
<NumberOfSegments>6</NumberOfSegments>
</OrangeFruit>
</Fruits>
所以我尝试以下方法:
[Serializable]
[XmlInclude(typeof(Apple))]
[XmlInclude(typeof(Orange))]
public abstract class Fruit {
public bool IsRotten { get; set; }
}
[Serializable]
[XmlRoot("AppleFruit")]
public class Apple : Fruit {
public bool FellFarFromTree { get; set; }
}
[Serializable]
[XmlRoot("OrangeFruit")]
public class Orange : Fruit {
public int NumberOfSegments { get; set; }
}
public class Blender {
public void XmlBlend(params Fruit[] fruits) {
using (var writer = new XmlTextWriter(@"c:\test\blended_fruits.xml", Encoding.UTF8)) {
writer.Formatting = Formatting.Indented;
writer.WriteStartDocument();
writer.WriteStartElement("Fruits");
var serializer = new XmlSerializer(typeof (Fruit));
foreach (var fruit in fruits) {
serializer.Serialize(writer, fruit);
}
writer.WriteEndElement();
writer.WriteEndDocument();
}
}
[Test]
public void TestIt () {
var blender = new Blender();
blender.XmlBlend(
new Apple() {
FellFarFromTree = false,
IsRotten = true
},
new Orange() {
IsRotten = false,
NumberOfSegments = 6
});
}
}
但是XmlRoot属性似乎完全被忽略了。实际输出看起来像:
<Fruits>
<Fruit xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Apple">
<IsRotten>true</IsRotten>
<FellFarFromTree>false</FellFarFromTree>
</Fruit>
<Fruit xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Orange">
<IsRotten>false</IsRotten>
<NumberOfSegments>6</NumberOfSegments>
</Fruit>
</Fruits>
我错过了什么?
答案 0 :(得分:1)
回答我自己的解决方法,但如果有人有更好的答案,我会接受它。
我为每个类创建了一个不同的序列化程序,并将它们粘贴在字典中:
public Dictionary<Type, XmlSerializer> ShouldntHaveToDoThis = new Dictionary<Type, XmlSerializer>() {
{typeof(Apple), new XmlSerializer(typeof(Apple))},
{typeof(Orange), new XmlSerializer(typeof(Orange))}
};
然后为每个项目获取适当的序列化器:
foreach (var fruit in fruits) {
var serializer = ShouldntHaveToDoThis[fruit.GetType()];
serializer.Serialize(writer, fruit);
}
答案 1 :(得分:0)
执行此操作的一种方法是为Fruits
创建一个类型,其中包含每种Fruit
类型的列表,并使用XmlElement
属性命名项目。
[XmlRoot("Fruits")]
public class Fruits
{
[XmlElement("AppleFruit")]
public Apple[] Apples { get; set; }
[XmlElement("OrangeFruit")]
public Orange[] Oranges { get; set; }
}
[Serializable]
[XmlInclude(typeof(Apple))]
[XmlInclude(typeof(Orange))]
public abstract class Fruit {
public bool IsRotten { get; set; }
}
[Serializable]
public class Apple : Fruit {
public bool FellFarFromTree { get; set; }
}
[Serializable]
public class Orange : Fruit {
public int NumberOfSegments { get; set; }
}
public void XmlBlend(Fruits fruits) {
using (var writer = new XmlTextWriter(@"c:\test\blended_fruits.xml", Encoding.UTF8)) {
writer.Formatting = Formatting.Indented;
var serializer = new XmlSerializer(typeof(Fruits));
serializer.Serialize(writer, fruits);
}
}
生成输出,如:
<?xml version="1.0" encoding="utf-8"?>
<Fruits xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<AppleFruit>
<IsRotten>true</IsRotten>
<FellFarFromTree>false</FellFarFromTree>
</AppleFruit>
<OrangeFruit>
<IsRotten>false</IsRotten>
<NumberOfSegments>6</NumberOfSegments>
</OrangeFruit>
</Fruits>
必须列出Apple[] Apples
等等并不完美,但我认为它类似于[XmlInclude(typeof(Apple))]
上需要Fruit
。