在序列化为XML时重命名类我正在尝试序列化如下所示的外部类,并从序列化的XML创建一个XElement。它有一个属于Inner的属性。我想更改Inner(至Inner_X)和Outer(至Outer_X)的名称。类程序{staticvoidMain(string[]args){使用(MemoryStreammemoryStream=newMemoryStream()){使用(TextWriterstreamWriter=newStreamWriter(memoryStream)){varxmlSerializer=newXmlSerializer(typeof(Outer));XMLSerializer。序列化(streamWriter,newOuter());XElement结果=XElement.Parse(Encoding.ASCII.GetString(memoryStream.ToArray()));}}}}[XmlType("Outer_X")]publicclassOuter{publicOuter(){this.InnerItem=newInner();}publicInnerInnerItem{得到;放;}}[XmlType("Inner_X")]publicclassInner{}这将创建一个如下所示的XElement:我想要的是:我想保留有关如何使用该类重命名该类的信息。我以为我可以使用XmlType属性来执行此XmlType。但是,这将被忽略,而是使用属性名称。我看过这里和其他地方,觉得这应该行得通。我错过了什么?澄清通过“保留有关如何使用该类重命名该类的信息”,我的意思是术语Inner_X应该只出现在Inner类中。它不应出现在外部类中。当XmlSerializer序列化类型时,类型本身控制为其属性创建的元素的名称。也就是说,属性名称成为元素名称,除非被XmlElementAttribute.ElementName静态覆盖。XmlTypeAttribute.TypeName通常仅在其所应用的类型的实例未序列化为某个包含类型的属性时才控制元素名称——例如,当它是根元素时,或者当它包含在元素中时正在使用外部容器元素进行序列化。收集。如果给定类型中存在多个相同类型的属性,此设计可避免名称冲突。但是,在多态属性类型的情况下存在一个例外。对于这些,XmlSerializer可以选择使用每个可能的多态类型的XML类型名称作为元素名称,从而标识创建元素的实际c#类型。要启用此功能,必须将多个[XmlElement(typeof(TDerived))]属性添加到属性中,每个属性对应一种可能的TDerived类型。您可以使用此函数通过引入伪多态代理属性来生成所需的XML:[XmlType("Outer_X")]publicclassOuter{publicOuter(){this.InnerItem=newInner();}[XmlIgnore]publicInnerInnerItem{get;放;}[XmlElement(typeof(Inner))][XmlElement(typeof(object))][Browsable(false),EditorBrowsable(EditorBrowsableState.Never),DebuggerBrowsable(DebuggerBrowsableState.Never)]publicobjectInnerItemXmlProxy{get{returnInnerItem;}set{InnerItem=(Inner)value;然后根据需要输出:prototypefiddle。但是,正如@evk评论的那样,如果您的Outer类包含多个相同类型的属性,则不能执行此操作。要考虑的另一种选择:如果您只是不想在多个位置(即在[XmlType(stringname)]和[XmlElement(stringname)]属性中)手动复制类型为“Inner_X”的名称字符串,您可以这样做这通过使用类型名称成为publicconst来集中它们:[XmlType(Outer.XmlTypeName)]publicclassOuter{publicconststringXmlTypeName="Outer_X";publicOuter(){this.InnerItem=newInner();}[XmlElement(Inner.XmlTypeName)]publicInnerInnerItem{get;放;}}[XmlType(Inner.XmlTypeName)]publicclassInner{publicconststringXmlTypeName="Inner_X";更新我刚刚注意到你的评论我打算使用Inner作为抽象基类,每个子类将序列化为不同的元素名称。如果是这种情况,那么XmlSerializer确实可以使用XML类型名称作为元素名称-但前提是它可以静态确定属性类型实际上是多态的,因为存在多个[XmlElement(typeof(TDerived))]属性。因此,以下类将生成您需要的XML:[XmlType("Outer_X")]publicclassOuter{publicOuter(){this.InnerItem=newInnerX();}[XmlElement(typeof(InnerX))][XmlElement(typeof(Inner))]//即使Inner是抽象的,也需要通知序列化器多态性。publicInnerInnerItem{得到;放;}}publicabstractclassInner{}[XmlType("Inner_X")]publicclassInnerX:Inner{}您需要设置属性的元素名称,而不是内部类的xml类型。试试这个:[XmlType("Outer_X")]publicclassOuter{publicOuter(){this.InnerItem=newInner();}[XmlElement("Inner_X")]publicInnerInnerItem{get;放;}}publicclassInner{}这很简单。您需要对类使用XmlRootAttribute,对成员使用XmlElementAttribute,如MSDN中所述。[XmlRoot(ElementName="Outer_X")]publicclassOuter{[XmlElement(ElementName="Inner_X")]publicInnerInnerItem{get;放;}=新的内部();}publicclassInner{}我创建了一个有效的.NETFiddle来说明这一点。ThisSOQ&A似乎解决了这个类似的问题。最后,在将XML解码为字符串时应该使用不同的编码,不是吗?据此,该字符串是UTF-16编码的——没什么大不了的,但我想知道这一点。我在以下XML中共享的小提琴结果:更新在您澄清问题后,我现在明白您在问什么。不幸的是,(据我所知)这不能通过属性来控制。您必须创建自己的XML序列化器/反序列化器,或者接受属性支持有限的事实。以上就是《C#学习教程:序列化为XML时重命名类》的全部内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。涉及侵权,请点击维权联系管理员删除。如需转载请注明出处:
