反序列化同一个类的替代名称

时间:2017-11-21 10:30:10

标签: c# xmlserializer

我有一个与以下内容完全不同的序列号:

[Serializable]
public class MSG
{
    [XmlAttribute]
    public string Name { get; set; } = string.Empty;

    [XmlText]
    public string Content { get; set; } = string.Empty;
}

public MSG DeserializeMyMsg(string xmlstr)
{
    TextReader reader = new StringReader(xmlstr);
    var serializer = new XmlSerializer(typeof(MSG));
    MSG ret = serializer.Deserialize(reader) as MSG;
    return ret;
}

这将成功反序列化以下内容:

<MSG Name="woho">any content</MSG>

有时,数据可能会以:

的形式到达
<Mg Name="woho">any content</Mg>

如何将Mg标记为MSG的替代名称?

MSG是根。固定镁将是长期目标,但也不是一种选择。消息可以用外根进行改装。

2 个答案:

答案 0 :(得分:1)

你在评论中提到你可以包装你的xml。这感觉非常像黑客,但这是有效的。一般来说,我的建议是不要这样做!

所以你的xml将是:

npm install angular2-jwt --save

或者

<NewRoot><MSG Name="woho">any content</MSG></NewRoot>

然后定义这些类并反序列化上面的xml:

<NewRoot><Mg Name="woho">any content</Mg></NewRoot>

答案 1 :(得分:1)

AFAIK,只能修改序列化属性是不可能的。但你可以做的是引入另一种具有不同属性的类型,然后调整反序列化逻辑以选择合适的序列化器。

遗产模型:

[XmlRoot("Mg")]
public class MSGLegacyWrapper : MSG { }

反序列化逻辑:

public static MSG DeserializeMyMsg(string xmlstr)
{
    using (var reader = new StringReader(xmlstr))
    using (var xmlreader = XmlReader.Create(reader))
    using (var serializationReader = new StringReader(xmlstr))
    {
        var serializer = new XmlSerializer(typeof(MSG));
        var chosenSerializer = serializer.CanDeserialize(xmlreader)
            ? serializer 
            : new XmlSerializer(typeof(MSGLegacyWrapper));
        return chosenSerializer.Deserialize(serializationReader) as MSG;
    }
}

Ofc可能会进一步拉扯,以优化决策过程。

备选方案1

如果您已经预处理了输入,那么您也可以在反序列化为强类型模型之前使用字符串操作(ex regex)规范化根​​标记名称。

备选方案2

如果您的架构足够简单/稳定,则可以删除基于属性的反序列化并实现您自己的自定义XmlReader,它可以处理其他根元素。请参阅文档和示例from MSDN。 我相信如果性能很重要,那么这是最快的选择。