是否有本地方式映射以下xml ...
<Tag type="1" />
<Tag type="2" />
...具体类“Type1Tag”和“Type2Tag”(都来自抽象类Tag),基于“type”属性的值?
(类似于NHibernate的鉴别器:DiscriminateSubClassesOnColumn(...)/ DiscriminatorValue(...))
我不是在寻找XmlSerializer + Polymorphism中报告的映射,它通过标记名称来区分类型,而不是通过属性值(我不能更改xml结构)来区分:)
答案 0 :(得分:3)
我在你的实施中可能为时已晚,无法提供任何帮助,但这是我周末想到的事情,并认为我会分享给其他人,因为它似乎满足了我的需求。
请注意,此处没有错误处理,您可以根据需要创建自己的子对象类型初始化。
我有许多不同的类,它们都是相同类型的元素,但可以根据属性的值保存不同的内容。
我使用IXmlSerializable
- 接口并实现了方法来读取每个类型标记...
Xml输入:
<Parent>
<Tag type="1"/>
<Tag type="2"/>
</Parent>
父类实现IXmlSerializable
:
public class Parent : IXmlSerializable
{
[XmlElement("Tag")]
public List<TagBase> Tags { get; set; }
#region IXmlSerializable Members
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
// this line causes the root Parent node to be ignored, and gets to the children Tag elements
reader.Read();
while (reader.ReadToNextSibling("Tag"))
{
string attributeType = reader.GetAttribute("type");
Type type = null;
switch(attributeType)
{
case "1":
type = typeof(Type1Tag);
break;
case "2":
type = typeof(Type2Tag);
break;
default:
continue;
}
XmlSerializer serializer = new XmlSerializer(type);
// this line is the key to rejoining the automatic xml deserialization of all
// the child stuff
TagBase tagBase = (TagBase)serializer.Deserialize(reader.ReadSubtree());
this.Tags.Add(tagBase);
}
}
public void WriteXml(System.Xml.XmlWriter writer)
{
throw new NotImplementedException();
}
#endregion IXmlSerializable Members
}
我创建了一个抽象的TagBase
- 类,每个标记类型都会继承:
[XmlRoot("Tag")]
public abstract class TagBase
{
[XmlAttribute("type")]
public string Type { get; set; }
}
然后,可以使用自定义属性等正常实现其他类...
[XmlRoot("Tag")]
public class Type1Tag : TagBase
{
// your implementation
}
[XmlRoot("Tag")]
public class Type2Tag : TagBase
{
// your implementation
}
注意,我在这里使用XmlRootAttribute
并包含它们,因为我有一堆命名空间在尝试反序列化子标记时导致异常,但是YMMV。我还没有达到添加WriteXml
- 方法的意义,但在这里应该非常简单......