简体   繁体   English

XML 序列化一个子 class

[英]XML serializing a sub class

I have a class:我有一个 class:

public abstract class BaseClass
{

}

public class FirstChild:BaseClass
{

}

public class SecondChild:BaseClass
{

}

public class Request
{
public BaseClass Child {get;set;}

}

I have added serializable attribute on all of the classes and included XmlInclude on Baseclass, firstchild and secondchild classes.我在所有类上添加了可序列化属性,并在 Baseclass、firstchild 和 secondchild 类中包含了 XmlInclude。

I want to achieve this:
<Request>
   <FirstChild/>
</Request>

or或者

<Request>
   <SecondChild/>
</Request>

I create the request using:我使用以下方法创建请求:

Request request = new Request();
request.Child = new FirstChild();

And then serialize it.然后序列化它。

but I keep getting this:但我不断得到这个:

<Request  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<Type  xsi:type="FirstChild">
</Type>

</Request>

Can you please point what I am not doing right?你能指出我做错了什么吗?

In order to do this you need to use the XmlArrayItem or XmlElement attributes.为此,您需要使用 XmlArrayItem 或 XmlElement 属性。 Also, if you want the sub-classed instance to be a sub-element of your Child element, it's easier if you treat the Child property as a BaseClass[] of length 1.此外,如果您希望子类实例成为 Child 元素的子元素,则将 Child 属性视为长度为 1 的 BaseClass[] 会更容易。

Thus your class will look like this:因此,您的 class 将如下所示:

public abstract class BaseClass
{

}

public class FirstChild:BaseClass
{

}

public class SecondChild:BaseClass
{

}

public class Request
{
        [XmlArrayItem(Type = typeof(FirstChild), ElementName = "FirstChild")]
        [XmlArrayItem(Type = typeof(SecondChild), ElementName = "SecondChild")] 
        public BaseClass[] Child {get;set;}

}

This will result in the XML you're looking for.这将产生您正在寻找的 XML。

Can you try this code.. also i'm assuming your actual class has properties in them.你能试试这个代码吗..我也假设你的实际 class 有属性。

using (MemoryStream ms = new MemoryStream())
{
    XmlWriterSettings xrs = new XmlWriterSettings();
    xrs.Encoding = Encoding.UTF8;
    using (XmlWriter writer = XmlWriter.Create(ms, xrs))
    {
        XmlSerializer serializer = new XmlSerializer(obj.GetType());
        serializer.Serialize(writer, obj);

        writer.Flush();
    }

    using (StreamReader sr = new StreamReader(ms))
    {
        ms.Position = 0;
        xml = sr.ReadToEnd();
    }
}

I don't see any easy way to do this.我没有看到任何简单的方法来做到这一点。 I would create a helper class RequestMemento for this purpose:为此,我将创建一个助手 class RequestMemento:

using System;
using System.IO;
using System.Xml.Serialization;
using System.ComponentModel;

public abstract class BaseClass
{}

public class FirstChild:BaseClass
{}

public class SecondChild:BaseClass
{}

[XmlRoot("Request")]
[XmlType("Request")]
public class RequestMemento
{
    [DefaultValue(null)]
    public FirstChild First { get; set; }

    [DefaultValue(null)]
    public SecondChild Second { get; set; }

    [XmlIgnore]
    public BaseClass Child
    {
        get
        {
            return (BaseClass)First ?? (BaseClass)Second;
        }
        set
        {
            First = value as FirstChild;
            Second = value as SecondChild;
        }
    }
}

class App
{
    static void Main()
    {
        var memento = new RequestMemento();
        memento.Child = new FirstChild();

        XmlSerializer serializer = new XmlSerializer(typeof(RequestMemento));
        using (var writer = new StreamWriter("1.xml"))
        {
            serializer.Serialize(writer, memento);
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM