简体   繁体   English

如何使用C#中的继承类实现Xml序列化

[英]How to implement Xml Serialization with inherited classes in C#

I have two classes : base class name Component and inheritd class named DBComponent 我有两个类:基类名称Component和名为DBComponent的继承类

[Serializable]
public class Component
{
    private string name = string.Empty;
    private string description = string.Empty;  
}

[Serializable]
public class DBComponent : Component
{
    private List<string> spFiles = new List<string>();

    // Storage Procedure Files
    [XmlArrayItem("SPFile", typeof(string))]
    [XmlArray("SPFiles")]
    public List<string> SPFiles
    {
        get { return spFiles; }
        set { spFiles = value; }
    }

    public DBComponent(string name, string description)
        : base(name, description)
    { }
}  

[Serializable]
public class ComponentsCollection
{
  private static ComponentsCollection instance = null;
  private List<Component> components = new List<Component>();

  public List<Component> Components
  {
      get { return components; }
      set 
      { 
            components = value; 
      }
  }

   public static ComponentsCollection GetInstance()
    {
        if (ccuInstance == null)
        {
            lock (lockObject)
            {
                if (instance == null)
                    PopulateComponents();
            }
        }
        return instance;
    }

    private static void PopulateComponents()
    {
        instance = new CCUniverse();
        XmlSerializer xs = new XmlSerializer(instance.GetType());
        instance = xs.Deserialize(XmlReader.Create("Components.xml")) as ComponentsCollection;
    }
}

} }

I want read\\write from a Xml file. 我想从Xml文件读取\\ write。 I know that I need to implement the Serialization for DBComponent class otherwise it will not read it.But i cannot find any simple article for that. 我知道我需要实现DBComponent类的序列化,否则它将无法读取它。但我找不到任何简单的文章。 all the articles that I found were too complex for this simple scenario. 我发现的所有文章对于这个简单的场景来说太复杂了。
The Xml file looks like this: Xml文件如下所示:

<?xml version="1.0" encoding="utf-8" ?>
  <ComponentsCollection>    
    <Components>
            <DBComponent Name="Tenant Historical Database" Description="Tenant Historical Database">
                    <SPFiles>
                        <SPFile>Setup\TenantHistoricalSP.sql</SPFile>
                    </SPFiles>
            </DBComponent>
            <Component Name="Agent" Description="Desktop Agent" />
        </Components>  
  </ComponentsCollection>

Can someone please give me a simple example of how to read this kind of xml file and what should be implemented ? 有人可以给我一个简单的例子来说明如何阅读这种xml文件以及应该实现什么?

Thanks 谢谢
Lior 利奥尔

Unfortunately, you need to tell the XmlSerializer the classes you intend to serialize or deserialize using the XmlArrayItem() attribute. 不幸的是,您需要使用XmlArrayItem()属性告诉XmlSerializer您要序列化或反序列化的类。 Each different type also needs its own element name. 每种不同的类型也需要自己的元素名称。 For example: 例如:

public class ComponentDerviedClass1: Component
public class ComponentDerivedClass2: Component
public class ComponentDerivedClass3: Component

// ...

public class ComponentsCollection
{
    [XmlArray("Components")]
    [XmlArrayItem("ComponentDerivedClass1", typeof(ComponentDerivedClass1))]
    [XmlArrayItem("ComponentDerivedClass2", typeof(ComponentDerivedClass2))]
    [XmlArrayItem("ComponentDerivedClass3", typeof(ComponentDerivedClass3))]
    public List<Component> Components
    {
        // ...
    }
}

This would read an XML file like: 这将读取一个XML文件,如:

<?xml version="1.0" encoding="utf-8" ?>
<ComponentsCollection>    
  <Components>
     <ComponentDerivedClass1>
         <!-- ... -->
     </ComponentDerivedClass1>
     <ComponentDerivedClass2>
         <!-- ... -->
     </ComponentDerivedClass2>
     <ComponentDerivedClass3>
         <!-- ... -->
     </ComponentDerivedClass3>
   </Components>  
</ComponentsCollection>

Multiple instances of each element can be present (or none). 可以存在每个元素的多个实例(或者不存在)。

Two options for different scenrios: tell the base-class 不同scenrios的两个选项:告诉基类

[XmlInclude(typeof(DBComponent))]
public class Component
{
    private string name = string.Empty;
    private string description = string.Empty;  
}

Or: tell the collection: 或者:告诉收藏:

[XmlArray]
[XmlArrayItem("Component", typeof(Component))]
[XmlArrayItem("DBComponent", typeof(DBComponent))]
public List<Component> Components {...}

Actually, you can also use [XmlElement(...)] in place of [XmlArrayItem] if you don't want the outer node (Components). 实际上,如果您不想要外部节点(Components),也可以使用[XmlElement(...)]代替[XmlArrayItem]。 Also: you don't need [Serializable]. 另外:您不需要[Serializable]。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM