Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.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节点的值将子对象反序列化到父对象列表(例如,list<;parent>;)中?_C#_Deserialization - Fatal编程技术网

C# 如何基于xml节点的值将子对象反序列化到父对象列表(例如,list<;parent>;)中?

C# 如何基于xml节点的值将子对象反序列化到父对象列表(例如,list<;parent>;)中?,c#,deserialization,C#,Deserialization,我有一个名为VehicleInfo的XML文件。 我想反序列化车辆列表中的车辆信息。 现在,我有一个名为Vehicle的基类和三个名为Car、Bike、Truck的派生类。 如何根据xml中车辆节点的值反序列化车辆的特定对象。 (例如,如果节点值为Car,则应将Car的对象存储在车辆列表中) 汽车 自行车 卡车 比如说, 车辆列表类别: public class VehicleList { List<Vehicle> lstVehicles = new List<V

我有一个名为VehicleInfo的XML文件。 我想反序列化车辆列表中的车辆信息。 现在,我有一个名为Vehicle的基类和三个名为Car、Bike、Truck的派生类。 如何根据xml中车辆节点的值反序列化车辆的特定对象。 (例如,如果节点值为Car,则应将Car的对象存储在车辆列表中)


汽车
自行车
卡车
比如说,

车辆列表类别:

public class VehicleList
{
    List<Vehicle> lstVehicles = new List<Vehicle>();
}
车辆等级:

public class Car : Vehicle
{
    public Car()
    {
        name = "Car";
    }
}
自行车等级:

public class Bike : Vehicle
{
    public Bike()
    {
        name = "Bike";
    }
}
卡车等级:

public class Truck : Vehicle
{
    public Truck()
    {
        name = "Truck";
    }
}
这个车辆程序只是一个例子


因此,如何根据节点Vehicle的值反序列化VehicleList类中Vehicle列表中的特定对象(如汽车、自行车或卡车)。

XmlSerializer
支持某些类型的继承建模,但是:它基于元素/属性,而不是实际值;我不知道有哪种API能够支持您从该数据中所需的内容,因此您必须将它们反序列化为字符串,并将它们后处理为您所需的内容

一个可能的例子是:


…汽车用品。。。
…自行车用品。。。
…卡车的东西。。。
可通过以下方式实现:

使用系统;
使用System.Collections.Generic;
使用System.Xml.Serialization;
[xmlclude(typeof(Car))]//从技术上讲,您只需要xmlclude
[xmlclude(typeof(Bike))]//如果您使用的是xsi:type解析
[xmlclude(typeof(Truck))]//但是。。。这对我们没有伤害
公共抽象类载体{}
公营车辆:车辆{}
公共类卡车:车辆{}
公共类自行车:车辆{}
[XmlRoot(“车辆”)]
公共类MyRoot
{
[XmlElement(“汽车”,类型=类型(汽车))]
[XmlElement(“卡车”,类型=类型(卡车))]
[xmlement(“Bike”,Type=typeof(Bike))]
公共列表项{get;}=new List();
}
静态P类
{
静态void Main()
{
var root=新的MyRoot
{
项目=
{
新车,
新自行车(),
新卡车(),
}
};
var ser=新的XmlSerializer(typeof(MyRoot));
var ns=新的XmlSerializerNamespaces();
加上(“,”);
序列化(Console.Out、root、ns);
}
}

以下是要序列化的代码和结果。XML不能将数组作为根元素。因此,在这种情况下,有两类是有意义的:车辆和车辆。见下面的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

namespace ConsoleApplication107
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            Vehicles vehicles = new Vehicles()
            {
                vehicles = new List<Vehicle>() {
                    new Car() { make = "BMW"},
                    new Bike() { make = "Buffalo"},
                    new Truck() { make = "MAC"}
                }
            };

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;

            XmlWriter writer = XmlWriter.Create(FILENAME, settings);
            XmlSerializer serializer = new XmlSerializer(typeof(Vehicles));
            serializer.Serialize(writer, vehicles);

        }
    }

    public class Vehicles
    {
        [XmlElement("Vehicle")]
        public List<Vehicle> vehicles { get; set; }
    }
    [XmlInclude(typeof(Car))]
    [XmlInclude(typeof(Bike))]
    [XmlInclude(typeof(Truck))]
    public class Vehicle
    {
        public string make { get; set; }
    }
    public class Car : Vehicle
    {
    }
    public class Bike : Vehicle
    {
    }
    public class Truck : Vehicle
    {
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Xml;
使用System.Xml.Serialization;
使用System.IO;
命名空间控制台应用程序107
{
班级计划
{
常量字符串文件名=@“c:\temp\test.xml”;
静态void Main(字符串[]参数)
{
车辆=新车()
{
车辆=新列表(){
新车(){make=“BMW”},
新自行车(){make=“Buffalo”},
新卡车(){make=“MAC”}
}
};
XmlWriterSettings=新的XmlWriterSettings();
settings.Indent=true;
XmlWriter=XmlWriter.Create(文件名、设置);
XmlSerializer serializer=新的XmlSerializer(类型(车辆));
序列化器。序列化(编写器、车辆);
}
}
公营车辆
{
[XmlElement(“车辆”)]
公共列表车辆{get;set;}
}
[xmlclude(类型(汽车))]
[xmlclude(类型(自行车))]
[xmlclude(卡车类型))]
公车
{
公共字符串make{get;set;}
}
公营车辆
{
}
公营自行车:汽车
{
}
公营货车
{
}
}
结果如下:

<?xml version="1.0" encoding="utf-8"?>
<Vehicles xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Vehicle xsi:type="Car">
    <make>BMW</make>
  </Vehicle>
  <Vehicle xsi:type="Bike">
    <make>Buffalo</make>
  </Vehicle>
  <Vehicle xsi:type="Truck">
    <make>MAC</make>
  </Vehicle>
</Vehicles>

宝马
水牛
雨衣

好的,这会很长时间

您可以使用此解决方案

使用Newtonsoft.Json;
使用制度;
使用System.Collections.Generic;
使用System.IO;
使用系统文本;
使用System.Xml.Serialization;
公共课程
{
公共静态void Main()
{
var根=新车辆
{
项目=
{
新车(){Name=“Car”},
新车(){Name=“Truck”},
新车(){Name=“Bike”}
}
};
var xmlSerializer=新的xmlSerializer(类型(车辆));
var memoryStream=新的memoryStream();
TextWriter stringWriter=新的StreamWriter(memoryStream,System.Text.Encoding.UTF8);
Serialize(stringWriter,root);
stringxml=System.Text.Encoding.UTF8.GetString(memoryStream.ToArray());
//生成XML
var obj=根;
var xmlString=obj.XmlSerializeToString();
//使用直接反序列化生成对象
var vehicles=xmlString.XmlDeserializeFromString();
//使用一些“逻辑”从通用车辆生成多态对象
var polymorphicVehicles=new List();//****这是您请求的集合*********
//对所有车辆进行评级
foreach(车辆中的var项目。项目)
{
//使用json序列化,因为不能将父对象强制转换为子对象
var jsonVehicle=JsonConvert.serialized对象(项);
//根据车辆名称,创建相应的对象
开关(项目名称)
{
案例“汽车”:
var aCar=JsonConvert.DeserializeObject(jsonVehicle);
多态性车辆添加(aCar);
打破
案例“卡车”:
var aTruck=JsonConvert.DeserializeObject(jsonVehicle);
多态车辆添加(aTruck);
打破
案例“自行车”:
<?xml version="1.0" encoding="utf-8"?>
<Vehicles xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Vehicle xsi:type="Car">
    <make>BMW</make>
  </Vehicle>
  <Vehicle xsi:type="Bike">
    <make>Buffalo</make>
  </Vehicle>
  <Vehicle xsi:type="Truck">
    <make>MAC</make>
  </Vehicle>
</Vehicles>
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml.Serialization;

public class Program
{
    public static void Main()
    {
        var root = new Vehicles
        {
            Items =
            {
                new Vehicle() { Name = "Car"},
                new Vehicle() { Name = "Truck"},
                new Vehicle() { Name = "Bike"}
            }
        };
        var xmlSerializer = new XmlSerializer(typeof(Vehicles));

        var memoryStream = new MemoryStream();
        TextWriter stringWriter = new StreamWriter(memoryStream, System.Text.Encoding.UTF8);
        xmlSerializer.Serialize(stringWriter, root);

        string xml = System.Text.Encoding.UTF8.GetString(memoryStream.ToArray());


        //Make XML
        var obj = root;
        var xmlString = obj.XmlSerializeToString();

        //Make Object with Direct Deserialization
        var vehicles = xmlString.XmlDeserializeFromString<Vehicles>();

        //Make polymorphic object from generic vehicles with some "logic"
        var polymorphicVehicles = new List<Vehicle>();  // ******  THIS is the collection you requested!!!! *********

        // itterate all vehicles
        foreach (var item in vehicles.Items)
        {
            // use json serialization, because casting Parent to Child is not acceptable
            var jsonVehicle = JsonConvert.SerializeObject(item);

            // depending on the Name of the vehicle, create a corresponding object
            switch (item.Name)
            {
                case "Car":
                    var aCar = JsonConvert.DeserializeObject<Car>(jsonVehicle);
                    polymorphicVehicles.Add(aCar);
                    break;
                case "Truck":
                    var aTruck = JsonConvert.DeserializeObject<Truck>(jsonVehicle);
                    polymorphicVehicles.Add(aTruck);
                    break;
                case "Bike":
                    var aBike = JsonConvert.DeserializeObject<Bike>(jsonVehicle);
                    polymorphicVehicles.Add(aBike);
                    break;
                default:
                    break;
            }
        }


        // this is just to print it out!
        var jsonPolymorphicVehicles = JsonConvert.SerializeObject(polymorphicVehicles);

        Console.WriteLine("XML:");
        Console.WriteLine(xml);

        Console.WriteLine("");

        Console.WriteLine("Polymorphic to jason");
        Console.WriteLine(jsonPolymorphicVehicles);

        Console.WriteLine("");
        Console.WriteLine("Press key to exit!");
        Console.Read();
    }


}



public class Vehicle
{
    public string Name = "Vehicle";
}

public class Car : Vehicle
{
    public Car()
    {
        Name = "Car";
    }
}

public class Bike : Vehicle
{
    public Bike()
    {
        Name = "Bike";
    }
}

public class Truck : Vehicle
{
    public Truck()
    {
        Name = "Truck";
    }
}

public class Vehicles
{
    public List<Vehicle> Items { get; } = new List<Vehicle>();
}


public static class MyStaticClass
{
    public static T XmlDeserializeFromString<T>(this string objectData)
    {
        return (T)XmlDeserializeFromString(objectData, typeof(T));
    }

    public static string XmlSerializeToString(this object objectInstance)
    {
        var serializer = new XmlSerializer(objectInstance.GetType());
        var sb = new StringBuilder();

        using (TextWriter writer = new StringWriter(sb))
        {
            serializer.Serialize(writer, objectInstance);
        }

        return sb.ToString();
    }

    public static object XmlDeserializeFromString(this string objectData, Type type)
    {
        var serializer = new XmlSerializer(type);
        object result;

        using (TextReader reader = new StringReader(objectData))
        {
            result = serializer.Deserialize(reader);
        }

        return result;
    }
}