序列化未知元素名称

时间:2017-12-10 01:10:08

标签: c# xml xml-serialization

我遇到了一个不太常见的XML结构的反序列化问题。 不幸的是,我对源站点没有任何影响。

XML有一个名为Bus的根,可以有多个Device个元素。 Device元素可以有多个值。 (好久不错)。

<Bus protocol="Meterbus" baud="2400">
    <Device Name="DHZ-1" PrimaryAddr="62">
        <Energie _="value" Name="Energie" size="13"/>
        <Spannung _="value" Name="Spannung" size="13"/>
        <Strom _="value" Name="Strom" size="13"/>
        <Leistung _="value" Name="Leistung" size="13"/>
        <Seriennummer _="value" Name="Seriennummer" size="13"/>
        <... _="..." Name="..." size=".."/>
    </Device>
</Bus>

问题是值具有完整的动态元素名称,但参数相同。

可能类似于<somename _="value" Name="somename" size="13"/>

但是无论名称是什么,它们都应该被序列化为Value类型。

这样的事情:

public class Value
{
    [XmlAttribute("_")]
    public String _
    {
        get;
        set;
    }

    [XmlAttribute("Name")]
    public String Name
    {
        get;
        set;
    }

    [XmlAttribute("size")]
    public String Size
    {
        get;
        set;
    }
}

Device类看起来像这样:

public class Device
{
    [XmlAttribute("Name")]
    public String Name
    {
        get;
        set;
    }

    [XmlAttribute("PrimaryAddr")]
    public String PrimaryAddr
    {
        get;
        set;
    }

    [???]
    public Array<Value> Values
    {
        get;
        set;
    }
}  

如何向序列化器解释这一点?

1 个答案:

答案 0 :(得分:2)

XmlSerializer类实现了一个UnknownElement事件,只要未定义/未知元素是解析器,就会调用该事件。您可以为此事件订阅处理程序并手动反序列化未定义/未知元素:

XmlSerializer serializer = new XmlSerializer(typeof(Bus));
serializer.UnknownElement += new XmlElementEventHandler(Serializer_UnknownElement);

一个有效的例子:

private void Serializer_UnknownElement(Object sender, XmlElementEventArgs e)
{
    var device = e.ObjectBeingDeserialized as Device;

    if (device != null)
    {
        XmlElement element = e.Element;  

        using (StringReader reader = new StringReader(element.OuterXml))
        {
            XmlSerializer valueSerializer = new XmlSerializer(typeof(Value), (new XmlRootAttribute(element.Name)));

            Value value = (Value)valueSerializer.Deserialize(reader);
            value.Name = element.Name; // implement it so you can rebuild the tag back

            device.Values.Add(value);
        }
    }
}

MSDN官方文档here