3

反序列化我有這樣的XML:C#與IXmlSerializable的

<data>  
    <audit_values> 
    <audit_value> 
     <channel>2</channel> 
     <week> 
     <mo_th>6,501698000000</mo_th> 
     <fr>8,414278000000</fr> 
     <sa>9,292674000000</sa> 
     <sun>8,551982000000</sun> 
     <holid>7,164605000000</holid> 
     </week> 
    </audit_value> 
    <audit_value> 
     <channel>1</channel> 
     <week> 
     <mo_th>6,501698000000</mo_th> 
     <fr>8,414278000000</fr> 
     <sa>9,292674000000</sa> 
     <sun>8,551982000000</sun> 
     <holid>7,164605000000</holid> 
     </week> 
    </audit_value> 
    </audit_values> 
</data> 

,我需要它反序列化類。 但問題是,這周將在未來的變化(這將是包含更多的元素,並把它們的名字我不知道)

數據:

[XmlRoot("data")] 
public class Data 
{ 
    [XmlArray("audit_values")] 
    [XmlArrayItem("audit_value", IsNullable = true)] 
    public AuditValue[] AuditValues { get; set; } 
} 

AuditValue:

[XmlRoot("audit_value")] 
public class AuditValue 
{ 
    [XmlElement("week", typeof(TVR))] 
    public Week Week; 
} 

周:

[XmlRoot("week")] 
public class Week : IXmlSerializable 
{ 
    public Dictionary<string, double> Values = new Dictionary<string, double>(); 

    public XmlSchema GetSchema() 
    { 
     return null; 
    } 

    public void ReadXml(XmlReader reader) 
    { 
     reader.Read(); 
     var sub = reader.ReadSubtree(); 
     do 
     { 
      if (sub.NodeType == XmlNodeType.Element) 
      { 
       string name = sub.Name; 
       string val = sub.ReadElementContentAsString(); 
       Values.Add(name, Convert.ToDouble(val)); 
      } 
     } while (sub.Read()); 
    } 

    public void WriteXml(XmlWriter writer) 
    { 

    } 
} 

但deserializat後離子我只有一個元素,只有一個字典值中記錄。我做錯了什麼?

GitHub上: https://github.com/olegletynain/XmlTest/tree/master/XmlTestRead

+0

[使用XmlSerializer反序列化隨機/未知類型](http:// stackoverflow。com/questions/8210386/deserialize-random-unknown-types-with-xmlserializer) – GSerg

+0

對不起,但我在實現IXmlSerializable時遇到了問題,並且沒有未知類型。它不是重複的 –

+0

您是否嘗試添加斷點並調試代碼? –

回答

2

我調整基於@Matthew粉飾在評論部分知道你的ReadXml方法和下面的方法做工作:

public void ReadXml(XmlReader reader) 
{ 
    Values = XElement.Parse(reader.ReadOuterXml()) 
     .Elements() 
     .ToDictionary(k => k.Name.ToString(), v => double.Parse(v.Value)); 
} 

作爲一個側面說明,你只需要XmlRoot實際的根元素不是每個所以我將它從AuditValue和Week中刪除。我也不知道TVR是什麼。它沒有用「typeof(TVR)」編譯,所以我也刪除了它。

爲了完整起見,這裏是我的版本的類:

[XmlRoot("data")] 
public class Data 
{ 
    [XmlArray("audit_values")] 
    [XmlArrayItem("audit_value", IsNullable = true)] 
    public AuditValue[] AuditValues { get; set; } 
} 

public class AuditValue 
{ 
    [XmlElement("week")] 
    public Week Week; 
} 

public class Week : IXmlSerializable 
{ 
    public Dictionary<string, double> Values = new Dictionary<string, double>(); 

    public XmlSchema GetSchema() 
    { 
     return null; 
    } 

    public void ReadXml(XmlReader reader) 
    { 
     Values = XElement.Parse(reader.ReadOuterXml()) 
      .Elements() 
      .ToDictionary(k => k.Name.ToString(), v => double.Parse(v.Value)); 
    } 

    public void WriteXml(XmlWriter writer) 
    { 

    } 
} 
+0

謝謝,今晚我自己製作了一個方法,不使用XElement和Linq –

0

試試這個。 XmlElement消除了你沒有的標籤。值的末尾有一個額外的's'。

From 
    [XmlArray("audit_values")] 
    [XmlArrayItem("audit_value", IsNullable = true)] 
    public AuditValue[] AuditValues { get; set; } 
​To 
    [XmlElement("audit_value")] 
    public AuditValue[] AuditValues { get; set; } 
+0

噢,對不起,第一次它是xml中的一個錯誤。 –

+0

您不需要兩級標籤只需。使用XlEement而不是XmlArray可以去掉不必要的標籤。 – jdweng

+0

對不起,但你錯了 –

1

你應該考慮使用DataContractSerializer的,而不是XmlSerializer的和執行上的DataContract類IExtensibleDataObject接口。

實現IExtensibleDataObject允許DataContract類在ExtensionData字段中保留未知信息,這樣可以防止在被反序列化的XML包含未知元素後丟失,然後重新序列化並保存。

你審計類將是這個樣子:

[DataContract(Name = "audit_value", Namespace = "")] 
public class AuditValue : IExtensibleDataObject 
{ 
    [DataMember(Name = "channel")] 
    public int Channel { get; set; } 

    [DataMember(Name = "week")] 
    public Week Week { get; set; } 

    public ExtensionDataObject ExtensionData { get; set; } 
} 

[DataContract(Name = "week", Namespace = "")] 
public class Week : IExtensibleDataObject 
{ 
    [DataMember(Name = "mo_th")] 
    public Decimal MondayThroughThursday { get; set; } 

    public ExtensionDataObject ExtensionData { get; set; } 
} 

你仍然需要更新您的代碼以反序列化的附加元素波蘇斯,但至少底層數據將一直持續到你身邊到它。

0

錯誤是在ReadXml方法,現在我把它改成這樣:

​​

我工作正常。此解決方案不使用XElement和Linq,@Volkan Paksoy提供了易於理解的XElement方法

相關問題