根据字段值反序列化

Deserialize dependent on field value

我需要反序列化 XML,它使用一个字段 "type" 来指示期望的内容。 类型 0 表示我可以期待简单的文本,而类型 1 表示内容具有更复杂的结构。

我知道我可以编写一些自定义反序列化机制,但想知道是否有任何内置方法可以解决这个问题。

由于 XMLSerializer 需要一个字符串,所以如果它是 XML,它会简单地丢弃内容。这阻止了我 运行 内容反序列化作为第二步。

<Msg>
    <MsgType>0</MsgType>
    <Data>Some text</Data>
</Msg>

<Msg>
    <MsgType>1</MsgType>
    <Data>
        <Document>
            <Type>PDF</Type>
            .....
        </Document>
    </Data>
</Msg>

开箱即用不支持;但是,您也许可以使用:

public XmlNode Data {get;set;}

和运行 "what to do with Data?"作为第二步,一旦你可以看看MsgType

完整示例:

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

static class P
{
    static void Main()
    {
        const string xml = @"<Foo>
<Msg>
    <MsgType>0</MsgType>
    <Data>Some text</Data>
</Msg>

<Msg>
    <MsgType>1</MsgType>
    <Data>
        <Document>
            <Type>PDF</Type>
            .....
        </Document>
    </Data>
</Msg>
</Foo>";
        var fooSerializer = new XmlSerializer(typeof(Foo));
        var docSerializer = new XmlSerializer(typeof(Document));
        var obj = (Foo)fooSerializer.Deserialize(new StringReader(xml));

        foreach (var msg in obj.Messages)
        {
            switch (msg.MessageType)
            {
                case 0:
                    var text = msg.Data.InnerText;
                    Console.WriteLine($"text: {text}");
                    break;
                case 1:
                    var doc = (Document)docSerializer.Deserialize(new XmlNodeReader(msg.Data));
                    Console.WriteLine($"document of type: {doc.Type}");
                    break;
            }
            Console.WriteLine();
        }
    }
}
public class Foo
{
    [XmlElement("Msg")]
    public List<Message> Messages { get; } = new List<Message>();
}
public class Message
{
    [XmlElement("MsgType")]
    public int MessageType { get; set; }

    public XmlNode Data { get; set; }
}

public class Document
{
    public string Type { get; set; }
}