序列化 XML 未知元素名称数组
Serialize XML array of unknown element name
我对一个不太常见的 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
class 看起来像这样:
public class Device
{
[XmlAttribute("Name")]
public String Name
{
get;
set;
}
[XmlAttribute("PrimaryAddr")]
public String PrimaryAddr
{
get;
set;
}
[???]
public Array<Value> Values
{
get;
set;
}
}
我该如何向序列化程序解释这一点?
XmlSerializer
class 实现了一个 UnknownElement
事件,每当解析 undefined/unknown 元素时就会调用该事件。您可以订阅此事件的处理程序并手动反序列化 undefined/unknown 元素:
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。
我对一个不太常见的 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
class 看起来像这样:
public class Device
{
[XmlAttribute("Name")]
public String Name
{
get;
set;
}
[XmlAttribute("PrimaryAddr")]
public String PrimaryAddr
{
get;
set;
}
[???]
public Array<Value> Values
{
get;
set;
}
}
我该如何向序列化程序解释这一点?
XmlSerializer
class 实现了一个 UnknownElement
事件,每当解析 undefined/unknown 元素时就会调用该事件。您可以订阅此事件的处理程序并手动反序列化 undefined/unknown 元素:
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。