正确的派生类的XML表示

时间:2014-08-07 01:44:48

标签: c# xml serialization

所以我有以下基类和派生类:

[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; }
    }
}

2 个答案:

答案 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>