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