使用变体子项反序列化 XML
Deserialize XML with variant child
我有一个设备可以通过 TCP 随机生成 6 种不同类型的 XML 通知。我已经成功反序列化通知;但是,对于 1 个特定的通知、事件,我需要一些关于如何更有效地处理它的建议。
以下是事件通知的 3/36 示例:
Example 1
<event>
<property1>721695632</property1>
<property2>266</property2>
<class1>
<property31>dirk</property31>
<property32>192.168.1.110</property32>
<property33>fx</property33>
</class1>
</event>
Example 2
<event>
<property1>721555130</property1>
<property2>263</property2>
<class2>
<property41>00-00-00-00-00-00-00-00</property41>
<property42>569</property42>
</class2>
</event>
Example 3
<event>
<property1>724342931</property1>
<property2>326</property2>
<class3>
<property51>23</property51>
<property52>00-00-00-00-00-00-00-02</property52>
<property53>100.00</property53>
<property54>0000AF72B7C12094EE833326234</property54>
</class3>
</event>
事件通知之间的唯一共同点是根节点以及 属性1 和 属性2 节点。其余节点因不同事件而异。为了反序列化事件通知,我创建了以下 classes:
public class Event
{
public ulong Property1 {get; set;}
public int Property2 {get; set;}
public class1 Property3 {get; set;}
public class2 Property4 {get; set;}
public class3 Property5 {get; set;}
}
public class1
{
public string Property31 {get; set;}
public string Property32 {get; set;}
public string Property32 {get; set;}
}
public class2
{
public string Property41 {get; set;}
public int Property42 {get; set;}
}
public class3
{
public int Property51 {get; set;}
public string Property52 {get; set;}
public double Property53 {get; set;}
public string Property54 {get; set;}
}
我使用事件 class 反序列化事件通知。反序列化后,我循环遍历事件 class 中的所有属性以搜索属性 != null。总是有 3 个非空属性。 Property1 和 Property2 始终保证不为空,并且 属性 3,4 或 5 不为空。非空属性传递给这个新的 class:
public class EventResult
{
public ulong Property1 {get; set;}
public int Property2 {get; set;}
public Object EventType {get; set;}
}
现在我有了一个漂亮整洁的 class,只有有效的属性。
这是我正在努力改进的地方。我想摆脱循环部分并将事件通知反序列化为正确的对应 class,只有有效属性。
public class Event1
{
public ulong Property1 {get; set;}
public int Property2 {get; set;}
public class1 Event {get; set;}
}
public class Event2
{
public ulong Property1 {get; set;}
public int Property2 {get; set;}
public class2 Event {get; set;}
}
public class Event3
{
public ulong Property1 {get; set;}
public int Property2 {get; set;}
public class3 Event {get; set;}
}
我在想我可以使用 EventResult class 来反序列化事件通知;但是,我认为这行不通,因为 XMLElement 属性对于 class1、class2 和 class3 是不同的。
非常感谢有关此主题的任何帮助或讨论。
提前致谢。
您可以通过使用多个 [XmlElement(String, Type)]
属性,一个代表 object
的每个可能的子 class 可能作为 属性 值遇到的子class,给出每个要使用的元素名称:
[XmlRoot("event")]
public class EventResult
{
[XmlElement("property1")]
public ulong Property1 { get; set; }
[XmlElement("property2")]
public int Property2 { get; set; }
[XmlElement("class1", typeof(class1))]
[XmlElement("class2", typeof(class2))]
[XmlElement("class3", typeof(class3))]
public Object EventType { get; set; }
}
然后所有三个示例 XML 文件都可以一步反序列化。
为了安全起见,我会推荐
- 使所有
EventType
class 继承自某些基础 class 或接口,或
- 在
EventType
的 setter 中,确保传入的 value
是已知类型之一。如果不是,抛出一个 ArgumentException
.
使 classes 继承事件 class
[XmlInclude(typeof(class1))]
[XmlInclude(typeof(class2))]
[XmlInclude(typeof(class3))]
[Serializable]
[XmlRoot(ElementName = "event")]
public class Event
{
[XmlElement("property1")]
public ulong Property1 {get; set;}
[XmlElement("property2")]
public int Property2 { get; set; }
}
[Serializable]
[XmlRoot(ElementName = "class1")]
public class class1 : Event
{
[XmlElement("property31")]
public string Property31 { get; set; }
[XmlElement("property32")]
public string Property32 { get; set; }
[XmlElement("property33")]
public string Property33 { get; set; }
}
[Serializable]
[XmlRoot(ElementName = "class2")]
public class class2 : Event
{
[XmlElement("property41")]
public string Property41 { get; set; }
[XmlElement("property42")]
public int Property42 { get; set; }
}
[Serializable]
[XmlRoot(ElementName = "class3")]
public class class3 : Event
{
[XmlElement("property51")]
public int Property51 { get; set; }
[XmlElement("property52")]
public string Property52 { get; set; }
[XmlElement("property53")]
public double Property53 { get; set; }
[XmlElement("property54")]
public string Property54 { get; set; }
}
我有一个设备可以通过 TCP 随机生成 6 种不同类型的 XML 通知。我已经成功反序列化通知;但是,对于 1 个特定的通知、事件,我需要一些关于如何更有效地处理它的建议。
以下是事件通知的 3/36 示例:
Example 1
<event>
<property1>721695632</property1>
<property2>266</property2>
<class1>
<property31>dirk</property31>
<property32>192.168.1.110</property32>
<property33>fx</property33>
</class1>
</event>
Example 2
<event>
<property1>721555130</property1>
<property2>263</property2>
<class2>
<property41>00-00-00-00-00-00-00-00</property41>
<property42>569</property42>
</class2>
</event>
Example 3
<event>
<property1>724342931</property1>
<property2>326</property2>
<class3>
<property51>23</property51>
<property52>00-00-00-00-00-00-00-02</property52>
<property53>100.00</property53>
<property54>0000AF72B7C12094EE833326234</property54>
</class3>
</event>
事件通知之间的唯一共同点是根节点以及 属性1 和 属性2 节点。其余节点因不同事件而异。为了反序列化事件通知,我创建了以下 classes:
public class Event
{
public ulong Property1 {get; set;}
public int Property2 {get; set;}
public class1 Property3 {get; set;}
public class2 Property4 {get; set;}
public class3 Property5 {get; set;}
}
public class1
{
public string Property31 {get; set;}
public string Property32 {get; set;}
public string Property32 {get; set;}
}
public class2
{
public string Property41 {get; set;}
public int Property42 {get; set;}
}
public class3
{
public int Property51 {get; set;}
public string Property52 {get; set;}
public double Property53 {get; set;}
public string Property54 {get; set;}
}
我使用事件 class 反序列化事件通知。反序列化后,我循环遍历事件 class 中的所有属性以搜索属性 != null。总是有 3 个非空属性。 Property1 和 Property2 始终保证不为空,并且 属性 3,4 或 5 不为空。非空属性传递给这个新的 class:
public class EventResult
{
public ulong Property1 {get; set;}
public int Property2 {get; set;}
public Object EventType {get; set;}
}
现在我有了一个漂亮整洁的 class,只有有效的属性。
这是我正在努力改进的地方。我想摆脱循环部分并将事件通知反序列化为正确的对应 class,只有有效属性。
public class Event1
{
public ulong Property1 {get; set;}
public int Property2 {get; set;}
public class1 Event {get; set;}
}
public class Event2
{
public ulong Property1 {get; set;}
public int Property2 {get; set;}
public class2 Event {get; set;}
}
public class Event3
{
public ulong Property1 {get; set;}
public int Property2 {get; set;}
public class3 Event {get; set;}
}
我在想我可以使用 EventResult class 来反序列化事件通知;但是,我认为这行不通,因为 XMLElement 属性对于 class1、class2 和 class3 是不同的。
非常感谢有关此主题的任何帮助或讨论。
提前致谢。
您可以通过使用多个 [XmlElement(String, Type)]
属性,一个代表 object
的每个可能的子 class 可能作为 属性 值遇到的子class,给出每个要使用的元素名称:
[XmlRoot("event")]
public class EventResult
{
[XmlElement("property1")]
public ulong Property1 { get; set; }
[XmlElement("property2")]
public int Property2 { get; set; }
[XmlElement("class1", typeof(class1))]
[XmlElement("class2", typeof(class2))]
[XmlElement("class3", typeof(class3))]
public Object EventType { get; set; }
}
然后所有三个示例 XML 文件都可以一步反序列化。
为了安全起见,我会推荐
- 使所有
EventType
class 继承自某些基础 class 或接口,或 - 在
EventType
的 setter 中,确保传入的value
是已知类型之一。如果不是,抛出一个ArgumentException
.
使 classes 继承事件 class
[XmlInclude(typeof(class1))]
[XmlInclude(typeof(class2))]
[XmlInclude(typeof(class3))]
[Serializable]
[XmlRoot(ElementName = "event")]
public class Event
{
[XmlElement("property1")]
public ulong Property1 {get; set;}
[XmlElement("property2")]
public int Property2 { get; set; }
}
[Serializable]
[XmlRoot(ElementName = "class1")]
public class class1 : Event
{
[XmlElement("property31")]
public string Property31 { get; set; }
[XmlElement("property32")]
public string Property32 { get; set; }
[XmlElement("property33")]
public string Property33 { get; set; }
}
[Serializable]
[XmlRoot(ElementName = "class2")]
public class class2 : Event
{
[XmlElement("property41")]
public string Property41 { get; set; }
[XmlElement("property42")]
public int Property42 { get; set; }
}
[Serializable]
[XmlRoot(ElementName = "class3")]
public class class3 : Event
{
[XmlElement("property51")]
public int Property51 { get; set; }
[XmlElement("property52")]
public string Property52 { get; set; }
[XmlElement("property53")]
public double Property53 { get; set; }
[XmlElement("property54")]
public string Property54 { get; set; }
}