Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 能否将旧版本的xml反序列化为新的结构_C#_.net_Xml_Deserialization_Xmlserializer_Automapper - Fatal编程技术网

C# 能否将旧版本的xml反序列化为新的结构

C# 能否将旧版本的xml反序列化为新的结构,c#,.net,xml,deserialization,xmlserializer,automapper,C#,.net,Xml,Deserialization,Xmlserializer,Automapper,我正在尝试更新正在反序列化的对象。获取一个对象、重命名、使用零件并添加一个新对象以容纳其余对象。NET中是否有方法将旧XML反序列化为新格式 e、 g 旧结构: <objectinfo> <element1></element1> <element2></element2> <element3></element3> <element4></element4> </objectinf

我正在尝试更新正在反序列化的对象。获取一个对象、重命名、使用零件并添加一个新对象以容纳其余对象。NET中是否有方法将旧XML反序列化为新格式

e、 g

旧结构:

<objectinfo>
<element1></element1>
<element2></element2>
<element3></element3>
<element4></element4>
</objectinfo>
<objinfo>
<element1></element1>
<element2></element2>
</objinfo>  

<newobject>
<element3></element3>
<element4></element4>
</newobject>

新结构:

<objectinfo>
<element1></element1>
<element2></element2>
<element3></element3>
<element4></element4>
</objectinfo>
<objinfo>
<element1></element1>
<element2></element2>
</objinfo>  

<newobject>
<element3></element3>
<element4></element4>
</newobject>

注意:我正在使用
XmlSerializer
进行反序列化。

假设您正在使用进行反序列化,如果您的
是根XML元素的直接子元素,则反序列化到与旧类型相同的某个类型,并手动或通过映射到新对象,可以非常轻松地解决问题

但是,如果被修改的对象深入嵌套在反序列化的对象层次结构中,那么DTO策略就不那么方便了,因为
XmlSerializer
不提供一般的替代DTO替换机制。在这种情况下,另一种方法是手动处理事件中的未知元素

要以一般方式执行此操作,请介绍以下用于XML反序列化的接口和扩展方法:

public interface IUnknownElementHandler
{
    void OnUnknownElement(object sender, XmlElementEventArgs e);
}

public static partial class XmlSerializationHelper
{
    public static T LoadFromXml<T>(this string xmlString, XmlSerializer serializer = null)
    {
        serializer = serializer ?? new XmlSerializer(typeof(T)).AddUnknownElementHandler();
        using (var reader = new StringReader(xmlString))
            return (T)serializer.Deserialize(reader);
    }

    public static T LoadFromFile<T>(string filename, XmlSerializer serializer = null)
    {
        serializer = serializer ?? new XmlSerializer(typeof(T)).AddUnknownElementHandler();
        using (var reader = new FileStream(filename, FileMode.Open))
            return (T)serializer.Deserialize(reader);
    }
    
    public static XmlSerializer AddUnknownElementHandler(this XmlSerializer serializer)
    {
        serializer.UnknownElement += (o, e) =>
        {
            var handler = e.ObjectBeingDeserialized as IUnknownElementHandler;
            if (handler != null)
                handler.OnUnknownElement(o, e);
        };
        return serializer;
    }
}
onUnknowneElement
处理程序添加到
ContainerType
中,如下所示:

public partial class ContainerType : IUnknownElementHandler
{
    #region IUnknownElementHandler Members

    void IUnknownElementHandler.OnUnknownElement(object sender, XmlElementEventArgs e)
    {
        var container = (ContainerType)e.ObjectBeingDeserialized;
    
        var element1 = e.Element.SelectSingleNode("element1");
        var element2 = e.Element.SelectSingleNode("element2");
        
        if (element1 != null || element2 != null)
        {
            container.Objinfo = container.Objinfo ?? new Objinfo();
            if (element1 != null)
                container.Objinfo.Element1 = element1.InnerText;
            if (element2 != null)
                container.Objinfo.Element2 = element2.InnerText;
        }
        
        var element3 = e.Element.SelectSingleNode("element3");
        var element4 = e.Element.SelectSingleNode("element4");
        if (element3 != null || element4 != null)
        {
            container.Newobject = container.Newobject ?? new Newobject();
            if (element3 != null)
                container.Newobject.Element3 = element3.InnerText;
            if (element4 != null)
                container.Newobject.Element4 = element4.InnerText;
        }
    }

    #endregion
}
然后,当您使用上面的
LoadFromFile
方法从文件中反序列化您的
Root
时:

var root = XmlSerializationHelper.LoadFromFile<Root>(filename);
var root=XmlSerializationHelper.LoadFromFile(文件名);
过时的未知XML元素将由
ContainerType
处理程序进行后处理


Demo fiddle。

使用旧类反序列化,然后使用新类重新序列化?当然,只需将旧结构反序列化为类,将数据复制到新类结构中,然后从新对象序列化。如果架构确实需要对象,则可以。反序列化只查看xml中的标记,将忽略与xml不匹配的类中的对象。在您的情况下,您将objectinfo的名称更改为objinfo,这将给出错误。谢谢。稍微调整一下就行了。