目前XmlSerializer产生以下结构:
<config>
<BaseType xsi:type="DerivedType1" />
<BaseType xsi:type="DerivedType2" />
</config>
有没有办法让它将类型名称放入节点:
<config>
<DerivedType1 />
<DerivedType2 />
</config>
答案 0 :(得分:26)
使用XmlElementAttribute
构造函数重载(string elementName, Type type)
。
它允许您替换在成员中找到的实际类型的元素名称。
如果您有多个派生类型,请将其中的几个堆叠在一起。
如果您尝试序列化可能包含Derived实例的List<Base>
等通用集合,请以相同方式使用XmlArrayItem
。
以这种方式定义也隐式地使派生类型已知,因此不需要XmlInclude
属性
样本定义:
[XmlRoot]
public class Data
{
[XmlElement("Derived1", typeof(Derived1))]
[XmlElement("Derived2", typeof(Derived2))]
public Base foo { get; set; }
[XmlArrayItem("Derived1", typeof(Derived1))]
[XmlArrayItem("Derived2", typeof(Derived2))]
public List<Base> fooList { get; set; }
}
public class Base { ... }
public class Derived1 : Base { ... }
public class Derived2 : Base { ... }
答案 1 :(得分:1)
为什么人们一直说“你永远无法反序列化”。 这在定义上是假的。
public class BaseClass {
public string Name {get;set;}
}
[XmlRoot("BaseClass")]
public class ChildClass : BaseClass {
public int Value {get;set;}
}
[XmlRoot("BaseClass")]
public class FlatClass
{
public string Name {get;set;}
public int Value {get;set;}
}
XmlSerializer ser1 = new XmlSerializer(typeof(BaseClass));
XmlSerializer ser2 = new XmlSerializer(typeof(ChildClass));
XmlSerializer ser3 = new XmlSerializer(typeof(FlatClass));
ser1.Serialize(File.Open("ser1.xml", FileMode.Create), new BaseClass(){Name="Base"});
ser2.Serialize(File.Open("ser2.xml", FileMode.Create), new ChildClass(){Name="Child",Value = 1});
ser1.Deserialize(File.OpenRead("ser2.xml"));
ser2.Deserialize(File.OpenRead("ser1.xml"));
ser3.Deserialize(File.OpenRead("ser2.xml"));
动臂。工作得很精致!!!!! 序列化完全符合这两种方式。生成的对象可能不是100%,但它反序列化。 Ser1在反序列化ser2.xml时忽略Value元素 Ser2 SKIPS在反序列化ser1.xml时的价值属性
打破这个模型的唯一因素是:
ser1.Serailize(File.Open("ser3.xml", FileMode.Create), new ChildClass(){Name = "Child2", Value = 2});
XmlSerialize ser3 = new XmlSerializer(typeof(FlatClass));
ser3.Deserialize(File.OpenRead("ser3.xml"));
这最后一次打破,因为BaseClass的Serializer遵循在元素上包含xsi:type =“ChildClass”属性的架构标准(尽管是有价值且99%的所需时间标准)。 Ser3无法处理该类型,因为它不依赖于该类型,特别是如果FlatClass存在于WAN或LAN线路的另一个程序集中。 就像Honey-badger一样,XmlSerailizer不关心元素或值,只要它能找到它们并且模式中的任何内容都不会破坏过程。 XSI:TYPE属性会破坏架构。
例如,当使用WCF或其他基于XML通信的系统时,如果Service有一个名为FlatClass的类,它就不会DESREIALIZE包含xsi:type =“”属性的ChildClass。但是,如果不对BaseClass使用序列化程序,它将反序列化完全相同的XML而不使用xsi:type属性。
Q.E.D。 NOT 包含xsi:type属性通常是有益的,必要的和可取的。
所以说有没有办法为BaseClass类型创建一个XmlSerializer,并告诉它在序列化子类型时不要包含xsi:type属性?
由于 Jaeden“Sifo Dyas”al'Raec Ruiner
答案 2 :(得分:0)
你可以用XmlElement Attrribute覆盖元素名称,例如
[XmlElement("DerivedType1")]
public BaseType : DerivedType1 {get;set;}
如果仍然会将xsi:type放入,并产生更大的混淆......
你的班级是什么样的?