XML 使用额外类型反序列化会抛出错误
XML deserialization with extra types throws error
我在反序列化之前不知道 XML 的类型。所以我使用 XmlSerializer
和 extraTypes
的重载。它确实适用于第一个 type
,但不适用于所有 extraTypes
。我收到以下错误消息 "System.InvalidOperationException: There is an error in XML document (1, 40). ---> System.InvalidOperationException: <Bike xmlns=''> was not expected."
。这是我要执行的操作的虚拟代码。
using System;
using System.IO;
using System.Xml.Serialization;
public class Program
{
private const string CarXml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Car xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"></Car>";
private const string BikeXml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Bike xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"></Bike>";
public static void Main(string[] args)
{
var xmlSerializer = new XmlSerializer(typeof(Car), new[] { typeof(Bike) });
using (var stringReader = new StringReader(BikeXml))
{
try
{
var vehicle = (Vehicle)xmlSerializer.Deserialize(stringReader);
Console.WriteLine(vehicle.PrintMe());
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
}
public abstract class Vehicle
{
public abstract string PrintMe();
}
public class Car : Vehicle
{
public override string PrintMe()
{
return "beep beep I'm a car!";
}
}
public class Bike : Vehicle
{
public override string PrintMe()
{
return "bing bing I'm a bike!";
}
}
显然 extraTypes
不适用于我的情况。参见 msdn documentation。
我通过获取 XmlRoot 解决了这个问题。
public static void Main(string[] args)
{
var xmlDocument = new XmlDocument();
xmlDocument.LoadXml(BikeXml);
var rootName = xmlDocument.DocumentElement.Name;
var rootType = Type.GetType(rootName);
var vehicle = rootType != null ? (Vehicle) Activator.CreateInstance(rootType) : null;
Console.WriteLine(vehicle != null ? vehicle.PrintMe() : "Error");
}
我在反序列化之前不知道 XML 的类型。所以我使用 XmlSerializer
和 extraTypes
的重载。它确实适用于第一个 type
,但不适用于所有 extraTypes
。我收到以下错误消息 "System.InvalidOperationException: There is an error in XML document (1, 40). ---> System.InvalidOperationException: <Bike xmlns=''> was not expected."
。这是我要执行的操作的虚拟代码。
using System;
using System.IO;
using System.Xml.Serialization;
public class Program
{
private const string CarXml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Car xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"></Car>";
private const string BikeXml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Bike xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"></Bike>";
public static void Main(string[] args)
{
var xmlSerializer = new XmlSerializer(typeof(Car), new[] { typeof(Bike) });
using (var stringReader = new StringReader(BikeXml))
{
try
{
var vehicle = (Vehicle)xmlSerializer.Deserialize(stringReader);
Console.WriteLine(vehicle.PrintMe());
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
}
public abstract class Vehicle
{
public abstract string PrintMe();
}
public class Car : Vehicle
{
public override string PrintMe()
{
return "beep beep I'm a car!";
}
}
public class Bike : Vehicle
{
public override string PrintMe()
{
return "bing bing I'm a bike!";
}
}
显然 extraTypes
不适用于我的情况。参见 msdn documentation。
我通过获取 XmlRoot 解决了这个问题。
public static void Main(string[] args)
{
var xmlDocument = new XmlDocument();
xmlDocument.LoadXml(BikeXml);
var rootName = xmlDocument.DocumentElement.Name;
var rootType = Type.GetType(rootName);
var vehicle = rootType != null ? (Vehicle) Activator.CreateInstance(rootType) : null;
Console.WriteLine(vehicle != null ? vehicle.PrintMe() : "Error");
}