2012-08-02 56 views
1

是否有映射以下XML原生方式....NET XmlSerializer的:根据属性值多态性映射

<Tag type="1" /> 
<Tag type="2" /> 

...到具体的类“Type1Tag”和“Type2Tag”(两者推导从抽象类标签),基于“type”属性的值?

(东西类似于NHibernate的鉴别:DiscriminateSubClassesOnColumn(...)/ DiscriminatorValue(...))

我不是寻找类似的XmlSerializer + Polymorphism报道映射,它通过标签名称区分类型,而不是通过一个属性值(我不能改变xml结构):)

回答

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 -method的意思,但在这里应该是非常简单的...

+0

谢谢,我会尽快查看它:) – Notoriousxl 2012-09-25 18:17:35