反序列化派生类型

时间:2014-10-22 08:50:54

标签: c# xml-serialization

我以为我终于理解了XmlSerialization,但是我的最后一种方法让我觉得它就像一个新手。 我的目的是创建一个框架,对某种配置进行序列化和反序列化。因此我创建了一个config-class,如下所示:

/// <summary>
/// Application-wide configurations that determine how to transform the features. 
/// </summary>
[XmlRoot(Namespace = "baseNS")]
public class Config
{
    /// <summary>
    /// List of all configuration-settings of this application
    /// </summary>
    [System.Xml.Serialization.XmlElement("Setting")]
    public List<Setting> Settings = new List<Setting>();
}

现在我需要某种配置,它定义了一个自定义设置列表。

/// <summary>
/// Application-wide configurations that determine how to transform the features. 
/// </summary>
[System.Xml.Serialization.XmlRoot("Config", Namespace = "baseNS")]
[System.Xml.Serialization.XmlInclude(typeof(BW_Setting))]
public class BW_Config : Config { 
    // nothing to add, only needed to include type BW_Setting
}


/// <summary>
/// Provides settings for one single type of source-feature specified by the <see cref="CQLQuery"/>-property. Only one target-featureType is possible for every setting. 
/// However settings for different targetTypes may have the same source-type provided. 
/// </summary>
[System.Xml.Serialization.XmlRoot("Setting", Namespace = "anotherNS")]
public class BW_Setting : Setting {
    // add and modify some attributes
}

据我所知,我将XmlInclude属性放在基类上(正在设置)。因此,设置和BW_Setting驻留在不同的程序集中,后者取决于前者我不能使用这种方法因为我得到一个圆引用。

这是实际序列化程序的代码:

XmlSerializer ser = new XmlSerializer(typeof(BW_Config));
BW_Config c = new BW_Config();
c.Settings.Add(new BW_Setting());
((BW_Setting)c.Settings[0]).CQLQuery = "test";

现在执行上述操作时,我收到错误"Type BW_Setting was not expected. Use XmlInclude..." 我可以更改自定义程序集中的所有内容,但因此基本属于框架我无法更改它。你能帮助我进行序列化(和反序列化)工作吗?

1 个答案:

答案 0 :(得分:0)

我终于通过定义一些覆盖来实现它:

// determine that the class BW_Setting overrides the elements within "Settings"
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
overrides.Add(
    typeof(Config), 
    "Settings", new XmlAttributes { 
        XmlElements = { 
            new XmlElementAttribute("Setting", typeof(BW_Setting)) } });
XmlSerializer ser = new XmlSerializer(typeof(Config), overrides);

这会产生以下输出

<?xml version="1.0"?>
<Config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="baseNS">
  <Setting id="0">
    <CQLQuery>test</CQLQuery>
  </Setting>
</Config>

唯一令人不快的是,标签设置的XML中的命名空间丢失了。然而,反序列化也有效,所以这并不令人讨厌。