2

我有一个包含模板(默认值)和指定字段的非标准 XML。作为一个例子总是受欢迎的:

<MyClass>
   <ArrayOfSubClass>
      <SubClass>
         <Par1>1</Par1>
         <Par2>2</Par2>
         <Par3>3</Par3>
         <ArrayOfSpecific>
            <Specific>
               <Par1>11</Par1>
            </Specific>
         </ArrayOfSpecific>
      </SubClass>
   </ArrayOfSubClass>
</MyClass>

我想将此类反序列MyClass化为一个对象。如您所见,MyClass是一个类的集合,SubClass它具有三个参数和一个类的集合Specific。类SubClassSpecific派生自同一个母类。

什么 ISpecific 我想找到默认值(即在 中找到的值SubClass),除非给出了一个字段。到目前为止,我所做的是实现一个方法,该方法通过反射检查类的属性是否具有属性类型的默认值,如果是这种情况,则将其Specific替换为属性。SubClass它工作得很好,但我没有涵盖所有情况。例如,假设我有一个 double 属性的值Par1SubClass比如Par1 = 1.234,但我希望它是 now 0。问题是这0是 double 类型的默认值,因此使用我的方法,我将检索SubClass.

最好的办法是首先反序列化MyClass对象,然后将Specific具有相同属性值的类的所有属性放入 中SubClass,然后再次反序列化到这个现有对象中,这将只更改 XML 文件中给出的属性。

这很棘手,我可以想象我的问题不容易理解......

[编辑:]为了更容易理解,这是我想要反序列化后的结果

<MyClass>
   <ArrayOfSubClass>
      <SubClass>
         <Par1>1</Par1>
         <Par2>2</Par2>
         <Par3>3</Par3>
         <ArrayOfSpecific>
            <Specific>
               <Par1>11</Par1>
               <Par2>2</Par2>
               <Par3>3</Par3>
            </Specific>
         </ArrayOfSpecific>
      </SubClass>
   </ArrayOfSubClass>
</MyClass>

反序列化后通过反射完成,如果 的属性Specific有默认值,则取类的值SubClass。棘手的情况如下

<MyClass>
   <ArrayOfSubClass>
      <SubClass>
         <Par1>1</Par1>
         <Par2>2</Par2>
         <Par3>3</Par3>
         <ArrayOfSpecific>
            <Specific>
               <Par1>0</Par1> <----- 0 is the default value of a double
            </Specific>
         </ArrayOfSpecific>
      </SubClass>
   </ArrayOfSubClass>
</MyClass>

目前结果将是

<MyClass>
   <ArrayOfSubClass>
      <SubClass>
         <Par1>1</Par1>
         <Par2>2</Par2>
         <Par3>3</Par3>
         <ArrayOfSpecific>
            <Specific>
               <Par1>1</Par1>   <---- as 0 is the default value of a double, this property is set to the value of the SubClass
               <Par2>2</Par2>
               <Par3>3</Par3>
            </Specific>
         </ArrayOfSpecific>
      </SubClass>
   </ArrayOfSubClass>
</MyClass>

但我想要

<MyClass>
   <ArrayOfSubClass>
      <SubClass>
         <Par1>1</Par1>
         <Par2>2</Par2>
         <Par3>3</Par3>
         <ArrayOfSpecific>
            <Specific>
               <Par1>0</Par1>
               <Par2>2</Par2>
               <Par3>3</Par3>
            </Specific>
         </ArrayOfSpecific>
      </SubClass>
   </ArrayOfSubClass>
</MyClass>
4

2 回答 2

0

以下是用于序列化的 CodeProject 链接的集合,可能会有所帮助:

虽然我不确定我是否理解您的问题,但您能否不让您的类可序列化,并且在 MyClass 示例中,为适当的值编写序列化代码?

于 2013-01-10T19:55:43.397 回答
0

好的,我找到了解决我的问题的解决方法。我分两步(实际上是三步)来做这件事。首先,我将 XML 反序列化到我的类中。其次,我将Specific类的所有属性设置为我在反射中找到的默认值SubClass,期望一个字段(Specific类的 If)。第三,我将 XML 重新加载到DataSet. 在那里,我查看DataTablenamed Specific,对于我的类的所有属性,我查看是否有任何同名的列,如果单元格包含一个值,我将它放在我的类中。

咳咳!!!!不是真正的美丽,但它确实有效。

     DataSet xmlDS = new DataSet();
     xmlDS.ReadXml(filename);
     GetSpecifiedValuesInDataSet(xmlDS);

     DataTable table = xmlDS.Tables["Specific"];

     foreach(ArrayOfSubClass array in this.Items)
     {
        foreach(SubClass sub in array)
        {
           foreach(Specific specific in sub)
           {
              Type specificType = specific.GetType();

              DataRow modelRow = null;
              foreach(DataRow row in table.Rows)
              {
                 if(row["Par1"].ToString().Equals(specific.Par1.ToString()))
                 {
                    modelRow = row;
                    break;
                 }
              }

              if(modelRow != null)
              {
                 foreach(PropertyInfo propSpecific in specificType.GetProperties())
                 {
                    string propertyName = propSpecific .Name;
                    foreach(DataColumn col in table.Columns)
                    {
                       if(col.ColumnName.Equals(propertyName))
                       {
                          if(!string.IsNullOrEmpty(modelRow[propertyName].ToString()))
                          {
                             object value = Convert.ChangeType(modelRow[propertyName], propSpecific.PropertyType);
                             propSpecific.SetValue(modelProd, value, null);
                          }
                       }
                    }
                 }
              }
           }
        }
     }

和瞧

于 2013-01-10T22:13:35.707 回答