C# 使用变量子级反序列化XML

C# 使用变量子级反序列化XML,c#,xml,class,object,deserialization,C#,Xml,Class,Object,Deserialization,我有一个设备,可以通过TCP随机生成6种不同类型的XML通知。我已经成功地反序列化了通知;然而,对于一个特殊的通知事件,我需要一些关于如何更有效地处理它的建议 以下是3/36个事件通知示例: Example 1 <event> <property1>721695632</property1> <property2>266</property2> <class1> <property31>dirk

我有一个设备,可以通过TCP随机生成6种不同类型的XML通知。我已经成功地反序列化了通知;然而,对于一个特殊的通知事件,我需要一些关于如何更有效地处理它的建议

以下是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>
我使用事件类反序列化事件通知。反序列化后,我在事件类中循环所有属性以搜索属性!=无效的始终有3个非空属性。属性1和属性2始终保证不为null,并且属性3、4或5都不为null。将非null属性传递给此新类:

public class EventResult
{
    public ulong Property1 {get; set;}
    public int Property2 {get; set;}
    public Object EventType {get; set;}
}
现在我有了一个漂亮整洁的类,只有有效的属性

这是我正在努力改进的地方。我想去掉循环部分,并将事件通知反序列化到只有有效属性的正确对应类中

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类来反序列化事件通知;但是,我认为这不起作用,因为class1、class2和class3的XMLElement属性不同

我非常感谢在这个话题上的任何帮助或讨论


提前感谢。

您可以直接反序列化到您的
事件结果
类,而无需任何中间类,方法是使用多个属性装饰
公共对象EventType{get;set;}
属性,每个属性对应可能遇到的
对象
的子类作为属性值,为每个元素指定要使用的元素名称:

[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
    类从某个基类或接口继承,或
  • EventType
    的setter中,确保传入的
    是已知类型之一。如果不是,则抛出一个
    ArgumentException

  • 使类继承事件类

        [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; }
        }​
    

    非常好的建议。非常感谢。看起来非常干净和简单。另外,当我将事件结果传递给我的csv类时,GetProperties顺序通常遵循声明顺序。另一个很好的建议。我的实际代码已经遵循了你的建议。我将公共属性放在抽象类中,抽象类必须由class1、class2、class3…………class36继承。我唯一缺少的是每个类上面的XML includes和XML根。
        [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; }
        }​