2013-11-28 32 views
7

我的第一个问题在SO:,)和它的约为XmlSerializer和命名空间问题。XmlSerializer +抽象类+派生类=无用命名空间

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

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

我已经创建了自己的序列化程序,它可以接受自定义命名空间或简单地忽略它们,它对于根元素来说工作得很好。

但是,当我使用抽象类列出列表中的某些派生类时,序列化插入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 

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

  • 使用命名空间= “” 属性
  • 实施XmlNamespaceDeclarations财产(用正确的空命名空间)
  • 从基地CLASE移动XmlRoot()派生一个
  • 更改XmlRoot()的XmlElement()

我会尽力在列表上添加XmlInclude标记以查看它是否改变了某些内容。

到目前为止,没有什么工作,以消除那些该死的命名空间......

如果任何人有一个解决方案,我会很高兴来试试吧。

[编辑21/02/2014] 好吧,似乎我是唯一一个面临这个问题。我将使用一个简单的字符串。替换删除无用的XML,但这很脏。


PS:对于背景下,标签是不是在另一端解析器一个问题,但不是在需要的时候,所以我正在寻找一种方法,以消除它们。

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

+0

我试着添加** [XmlArrayItem(“element”,Type = typeof(XmlDerivedClass))] **,但它解决了只有一个派生类的问题。 对于具有相同节点名称的多个派生类,它不适用于此系统。 – Ethenyl

回答

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 
+0

谢谢你,我会尽快尝试。 – Ethenyl

+0

现在我得到一个有趣的结果''。我将尝试使用** XmlTypeAttribute **来查看我是否可以更好地获得某些内容。 – Ethenyl

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; 
     } 
    } 
} 

相反XmlInclude,你可以创建一个派生类对象列表,之后的私有成员内把它们加起来也许缓存。 请再次注意,这仍然很不理想,但它适用于我,所以我想分享它。

+0

无论如何,如果您使用数组,您可以使用** XmlElement **和** XmlArrayItem **属性为您完成这项工作。 – user3194973