XmlSerializer +抽象类+派生类=无用的命名空间

时间:2013-11-28 10:45:46

标签: c# .net xml serialization xml-namespaces

关于 SO 的第一个问题:),它是关于 XmlSerializer 和名称空间问题。

我知道关于如何从Xml文件的根元素中删除默认的Xml命名空间已经有很多主题,而且它不是主题。

我的问题是当你使用派生类时如何从子节点中删除它?

我已经创建了自己的序列化程序,可以使用自定义命名空间或者只是忽略它们,并且它对根元素很有用。

但是当我使用抽象类在 List 中列出一些派生类时,每个派生类的节点内的序列化插入2属性。

像这样:

<root>
  <elements>
    <element p3:type="XmlDerivedClass" xmlns:p3="{schema_url}" >
    </element>
  </elements>
</root>

至于我的班级:

// Root element
[XmlRoot("root", Namespace="")]
public class XmlRootElement
{
    List<XmlBaseClass> _Elements;
}    

// Base class
[XmlInclude(typeof(XmlDerivedClass))] // Mandatory, prevents serialization errors
[XmlRoot(Namespace="")]
public abstract class XmlBaseClass

// Derived class
[XmlRoot("element", Namespace="")]
public class XmlDerivedClass : XmlBaseClass

我尝试了一些常见的解决方案:

  • 使用Namespace =“”属性
  • 实现 XmlNamespaceDeclarations 属性(使用右侧空命名空间)
  • XmlRoot()从base clase移动到派生的
  • XmlRoot()更改为 XmlElement()

我会尝试在列表上添加XmlInclude标记,看看它是否会发生变化。

到目前为止,没有任何方法可以删除那些该死的命名空间......

如果有人为此提供解决方案,我将很乐意尝试。

[EDIT 21/02/2014] 好吧,似乎我是唯一一个面临这个问题的人。我将使用一个简单的 string.Replace 来删除无用的XML,但这很脏。


PS:对于上下文,标签对于另一端的解析器不是问题,但它们不是必需的,所以我正在寻找一种方法来删除它们。

PS2:对于任何拼写错误,对不起,英语不是我的母语。

2 个答案:

答案 0 :(得分:2)

我不确定这是否是满足您需求的解决方案,因为它不是很好但是它有效并且看起来不太脏。

public abstract class Abs
{
    public int Data { get; set; }
}


public class A : Abs{}

public class B : Abs{}

[Serializable]
[XmlRoot(elementName: "name")]
public class Ser
{
    [XmlElement(elementName: "A")]
    public List<A> AList { get; set; }

    [XmlElement(elementName: "B")]
    public List<B> BList { get; set; }

    [XmlIgnore]
    public List<Abs> AbsList {
        get
        {
            var list = new List<Abs>(AList.ConvertAll(x=>(Abs)x));
            list.AddRange(BList.ConvertAll(x=>(Abs)x));
            return list;
        }
    }
}

您可以使用派生类对象创建List,然后将它们一起添加或者将它们缓存在私有成员中,而不是XmlInclude。 请再次注意,这仍然远非理想,但它对我有用,所以我想分享它。

答案 1 :(得分:0)

如果添加[XmlType],您可以为序列化程序提供有关类型的信息,例如它所属的命名空间:

// Base class
[XmlInclude(typeof(XmlDerivedClass))] // Mandatory, prevents serialization errors
[XmlType(Namespace="")]
public abstract class XmlBaseClass

// Derived class
[XmlType("element", Namespace="")]
public class XmlDerivedClass : XmlBaseClass