![](/img/trans.png)
[英]XML Serialization format needs to be very specific, how do you serialize child classes that have the same name as their parent class?
[英]XML Serialization: How to distinguish classes that use the same element name but have a different value in an attribute?
標題可能很長,請允許我解釋一下我的意思。 我不會為您提供需要使用的實際XML,但是我將給出一個演示我所面臨的問題的XML。
我有一個看起來像這樣的XML:
<root>
<creatures>
<creature type="mammal" name="lion">
<sound>roarr</sound>
</creature>
<creature type="bird" name="parrot">
<color>red</color>
</creature>
</creatures>
</root>
想象一下以下課程:
(當然,這些也不是我真正的課程,但您明白了。)
public class Creature
{
public string Name { get; set; }
}
public class MammalCreature : Creature
{
public string Sound { get; set; }
}
public class BirdCreature : Creature
{
public string Color { get; set; }
}
我想通過屬性使用XML序列化,我希望序列化BirdCreature
通過type
屬性區分MammalCreature
和BirdCreature
type
。
我已經找到了可以通過將xsi:type
屬性設置為所需的類型名稱來實現此目的的解決方案,但是我想知道是否有針對我的情況的實際解決方案。
不只是屬性,不。 但是,這些看起來長毛的代碼確實可以將XML正確地讀入Root
類:
[XmlRoot("root")]
public class Root : IXmlSerializable
{
[XmlElement("creatures")]
public Creatures Items { get; set; }
/// <summary>
/// This method is reserved and should not be used. When implementing
/// the IXmlSerializable interface, you should return null (Nothing in
/// Visual Basic) from this method, and instead, if specifying a custom
/// schema is required, apply the
/// <see cref="T:System.Xml.Serialization.XmlSchemaProviderAttribute"/>
/// to the class.
/// </summary>
/// <returns>
/// An <see cref="T:System.Xml.Schema.XmlSchema"/> that describes the
/// XML representation of the object that is produced by the
/// <see cref="M:System.Xml.Serialization.IXmlSerializable.WriteXml(System.Xml.XmlWriter)"/>
/// method and consumed by the
/// <see cref="M:System.Xml.Serialization.IXmlSerializable.ReadXml(System.Xml.XmlReader)"/>
/// method.
/// </returns>
public XmlSchema GetSchema()
{
return null;
}
/// <summary>
/// Generates an object from its XML representation.
/// </summary>
/// <param name="reader">The <see cref="T:System.Xml.XmlReader"/> stream
/// from which the object is deserialized. </param>
public void ReadXml(XmlReader reader)
{
reader.ReadStartElement("root");
reader.ReadStartElement("creatures");
List<Creature> creatures = new List<Creature>();
while ((reader.NodeType == XmlNodeType.Element)
&& (reader.Name == "creature"))
{
Creature creature;
string type = reader.GetAttribute("type");
string name = reader.GetAttribute("name");
reader.ReadStartElement("creature");
switch (type)
{
case "mammal":
MammalCreature mammalCreature = new MammalCreature();
reader.ReadStartElement("sound");
mammalCreature.Sound = reader.ReadContentAsString();
reader.ReadEndElement();
creature = mammalCreature;
break;
case "bird":
BirdCreature birdCreature = new BirdCreature();
reader.ReadStartElement("color");
birdCreature.Color = reader.ReadContentAsString();
reader.ReadEndElement();
creature = birdCreature;
break;
default:
reader.Skip();
creature = new Creature();
break;
}
reader.ReadEndElement();
creature.Name = name;
creature.Type = type;
creatures.Add(creature);
}
reader.ReadEndElement();
this.Items = new Creatures();
this.Items.Creature = creatures.ToArray();
reader.ReadEndElement();
}
/// <summary>
/// Converts an object into its XML representation.
/// </summary>
/// <param name="writer">The <see cref="T:System.Xml.XmlWriter"/> stream
/// to which the object is serialized. </param>
public void WriteXml(XmlWriter writer)
{
new XmlSerializer(typeof(Creatures)).Serialize(writer, this.Items);
}
}
[XmlRoot("creatures")]
public class Creatures
{
[XmlElement("creature")]
public Creature[] Creature { get; set; }
}
[XmlInclude(typeof(MammalCreature))]
[XmlInclude(typeof(BirdCreature))]
public class Creature
{
[XmlAttribute("type")]
public string Type { get; set; }
[XmlAttribute("name")]
public string Name { get; set; }
}
public class MammalCreature : Creature
{
[XmlElement("sound")]
public string Sound { get; set; }
}
public class BirdCreature : Creature
{
[XmlElement("color")]
public string Color { get; set; }
}
對於不同類型使用相同的Xml元素名稱對您來說真的很重要嗎?
如果您可以像這樣使用Xml,那么最終可能會變得更加簡單:
<root>
<creatures>
<MammalCreature name="lion">
<sound>roarr</sound>
</MammalCreature>
<Birdcreature name="parrot">
<color>red</color>
</BirdCreature>
</creatures>
</root>
XML序列化器不支持這種情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.