所以我有以下基类和派生类:
[XmlInclude(typeof(Circle))]
[XmlInclude(typeof(Square))]
public class Shape
{
public int XPos { get; set; }
public int YPos { get; set; }
}
public class Circle : Shape
{
public int Radius { get; set; }
}
public class Square : Shape
{
public int Side { get; set; }
}
如何在XML中表示Circle和Square,以便可以反序列化为新对象?
我在尝试:
<Shape type="Circle">
<Radius>10</Radius>
</Shape>
<Shape type="Square">
<Side>20</Side>
</Shape>
和
<Circle>
<Radius>10</Radius>
</Circle>
<Square>
<Side>20</Side>
</Square>
但它们都没有使用当前派生类(Square或Circle)加载Shape对象。第一个选项创建一个Square对象。第二个根本不创建任何对象。我正在使用C#MVC4。
[编辑 - 测试代码]
using System;
using System.Xml.Serialization;
using System.IO;
public class Program
{
public static void Main()
{
var shape = new Shape { XPos = 4, YPos = 5 };
Console.WriteLine(Serialize(shape));
Console.WriteLine();
var circle = new Circle { XPos = 1, YPos = 2, Radius = 3 };
Console.WriteLine(Serialize(circle));
Console.WriteLine();
var square = new Square { XPos = 2, YPos = 1, Side = 5 };
var ser = Serialize(square);
Console.WriteLine(square);
Square sq = Deserialize(ser);
Console.WriteLine(sq.Side);
}
public static string Serialize(Shape objectToSerialize)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Shape));
StringWriter textWriter = new StringWriter();
xmlSerializer.Serialize(textWriter, objectToSerialize);
return textWriter.ToString();
}
public static Square Deserialize(string ser)
{
XmlSerializer serializer = new XmlSerializer(typeof(Square));
using (StringReader reader = new StringReader(ser))
{
return (Square)(serializer.Deserialize(reader));
}
}
[XmlInclude(typeof(Circle))]
[XmlInclude(typeof(Square))]
public class Shape
{
public int XPos { get; set; }
public int YPos { get; set; }
}
public class Circle : Shape
{
public int Radius { get; set; }
}
public class Square : Shape
{
public int Side { get; set; }
}
}
答案 0 :(得分:1)
您将使用xsi:type
来声明Type
,例如xsi:type="Circle"
实施例
<Shape xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="Circle">
<XPos>1</XPos>
<YPos>2</YPos>
<Radius>3</Radius>
</Shape>
我的De / Serialize测试代码
var shape = new Circle { XPos = 1, YPos = 2, Radius = 3};
var ser = new XmlSerializer(typeof(Shape));
var xml = string.Empty;
using(var sw = new StringWriter())
{
ser.Serialize(sw, shape);
xml = sw.ToString();
}
using (var sr = new StringReader(xml))
{
var obj = ser.Deserialize(sr);
}
如果您需要一种简单的方法来返回强类型,则可以添加通用方法。
public T DeserializeShape<T>(string xml) where T : Shape
{
var ser = new XmlSerializer(typeof(Shape));
using (var sr = new StringReader(xml))
{
return (T)ser.Deserialize(sr);
}
}
var circle = DeserializeShape<Circle>(xml);
var square = DeserializeShape<Square>(xml); // etc....
答案 1 :(得分:1)
下面的两种方法将序列化和反序列化形状。反序列化方法是通用的,允许反序列化不同的形状。
我已经包含了序列化为XML的每个对象的示例。以下是用于创建示例的dot net fiddle。它还显示了如何反序列化对象。
<强>序列化强>
public static string Serialize(Shape objectToSerialize)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Shape));
StringWriter textWriter = new StringWriter();
xmlSerializer.Serialize(textWriter, objectToSerialize);
return textWriter.ToString();
}
反序列化
public static T Deserialize<T>(string xmlToDeserialize) where T : Shape
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Shape));
using (StringReader reader = new StringReader(xmlToDeserialize)) {
return (T)xmlSerializer.Deserialize(reader);
}
}
示例形式XML
<?xml version="1.0" encoding="utf-16"?>
<Shape xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<XPos>4</XPos>
<YPos>5</YPos>
</Shape>
示例圈XML
<?xml version="1.0" encoding="utf-16"?>
<Shape xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Circle">
<XPos>1</XPos>
<YPos>2</YPos>
<Radius>3</Radius>
</Shape>
示例Square XML
<?xml version="1.0" encoding="utf-16"?>
<Shape xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Square">
<XPos>2</XPos>
<YPos>1</YPos>
<Side>5</Side>
</Shape>