2017-06-02 78 views
0

我有一个类,看起来像这样:的XML C#反序列化过程中改变一个元素的名称

[XmlType(TypeName = "rootType")] 
public class myClass 
{ 
    public Class1 class1; 
    public Class2 class2; 

    [XmlType(TypeName = "type1")] 
    public class class1 
    { ... class1 definition ...} 
    [XmlType(TypeName = "type2")] 
    public class class2 
    { ... class1 definition ...}  

} 

当我序列化,生成的XML将

<rootType> 
    <class1> 
     ... some stuff 
    <class1/> 
    <class2> 
     ... some stuff 
    <class2/> 
<rootType/> 

然而,我的问题就在这里是这些xmltype装饰被添加到类中,这意味着在以前的版本(客户使用)中,xml看起来像

<myClass> 
    <type1> 
     ... some stuff 
    <type1/> 
    <type2> 
     ... some stuff 
    <type2/> 
<myClass/> 

有没有一种方法可以控制反序列化过程(或任何其他解决此问题的方法),如果可能,并且能够使用这些XmlType装饰将此xml反序列化为myClass?

+0

您可以转换旧的xml,并将其提供给您的新的反序列化器。这可能是最简单的。 – Rook

+0

@Rook,我仅限于不改变旧的xml – Santi

+0

但xml如何不可变形?您可以在第一次加载文件时在内存中执行此操作,或者可以将其转换为临时文件并加载该文件。 – Rook

回答

0

您的问题已完全解决。

首先,当您创建串行器时,请添加一个带有所需名称的XmlRootAttribute参数。

其次,将事件处理程序添加到序列化程序。

var serializer = new XmlSerializer(typeof(myClass), new XmlRootAttribute("myClass")); 
serializer.UnknownElement += Serializer_UnknownElement; 

事件处理程序应该是这样的:

void Serializer_UnknownElement(object sender, XmlElementEventArgs e) 
{ 
    myClass my = (myClass)e.ObjectBeingDeserialized; 

    if (e.Element.Name == "type1") 
    { 
     var ser = new XmlSerializer(typeof(myClass.Class1)); 
     using (var sr = new StringReader(e.Element.OuterXml)) 
      my.class1 = (myClass.Class1)ser.Deserialize(sr); 
    } 
    else if (e.Element.Name == "type2") 
    { 
     var ser = new XmlSerializer(typeof(myClass.Class2)); 
     using (var sr = new StringReader(e.Element.OuterXml)) 
      my.class2 = (myClass.Class2)ser.Deserialize(sr); 
    } 
} 

要一如既往地使用:

myClass my; 
using (var fs = new FileStream("test.xml", FileMode.Open)) 
    my = (myClass)serializer.Deserialize(fs); 

它应该工作。

+0

我会试试这个! – Santi

+0

这工作完美,谢谢! – Santi

相关问题