2013-01-10 50 views
2

我有一个包含模板(默认值)和指定字段的非标准XML。作为一个例子总是欢迎: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是​​类的集合,它有三个参数和一个类Specific的集合。类​​和Specific是从相同的母类派生的。

什么是特定的我想找到默认值(即在​​找到的值),除非给出一个字段。我到目前为止所做的是实现一种方法,通过反射检查类Specific的属性是否具有属性类型的默认值,如果属实,则将其替换为​​的属性。它工作得很好,但我没有涵盖所有的情况。例如,想象一下​​中的双重属性Par1的值,例如Par1 = 1.234,但我希望它现在为0。问题是0是double类型的默认值,所以在我的方法中,我将检索​​中的属性值。

最好将已先反序列化MyClass对象,然后把类Specific所有属性具有相同属性的​​的值,然后再反序列化到这个现有的对象,只改变了在给定的属性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的属性都有一个默认值,然后走班​​的价值。棘手的案件是遵循

<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> 
+0

我得到了那句话失去了:@“问题是,0是double类型的默认值,所以用我的方法,我将检索子类中的属性的值。 “ ,你是什么意思,为什么这是一个问题?如果你只是将这个值设置为零会发生什么? –

+0

你在做什么语言?这篇文章的标签是“c”,但由于你提到的是类和反射,我猜这是别的。 – JLRishe

+0

这是在c#对不起... – GuillaumeA

回答

0

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

Ouffffff !!!! 不是真的很美,但它有效。

 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); 
          } 
         } 
        } 
       } 
       } 
      } 
     } 
    } 

0

下面是序列化,可能是有益的CodeProject上的链接的集合:

虽然我不能肯定我明白你的问题,你能不能让你的类序列化,并在myClass例如,代码序列化的适当的值?

+0

我知道我的问题不清楚,但这是我能做的最好的:-(所有的类都是可序列化的 – GuillaumeA

+0

你能解释你的类的层次结构吗?你说SubClass和Specific都继承了相同的基类。是否更可行的实现一个接口呢? – Tebc

+0

我不知道我理解为什么一个接口会更好?基类只是一个容器的各种属性。目前,我将尝试的解决方案是一次反序列化,将类“SubClass”的所有值放入“Specific”类中,然后解析XML文件以查看该属性是否存在于XML中,以及是否存在用文件中给出的值覆盖它的值。 – GuillaumeA