2014-09-21 44 views
4

我在想如果你有關於如何調試下面的XML反序列化的提示嗎?我無法讓它工作。解串器基本上創建了summon和slash實例,但是它們的所有屬性都是空的。下面顯示了相關的類。如何調試XML反序列化?


SkillCollection類解串器:

[DataContract(Name = "Skills", Namespace = "")] 
public class SkillCollection 
{ 

[DataMember(Name = "Slash")] 
public Skill Slash { get; set; } 

[DataMember(Name = "Summon")] 
public Skill Summon { get; set; } 

public static object Deser(string path, Type toType) 
{ 
    var s = new DataContractSerializer(toType); 
    using (FileStream fs = File.Open(path, FileMode.Open)) 
    { 
     object s2 = s.ReadObject(fs); 
     if (s2 == null) 
      Console.WriteLine(@" Deserialized object is null"); 
     else 
      Console.WriteLine(@" Deserialized type: {0}", s2.GetType()); 
     return s2; 
    } 
} 

它是從另一個類通過屬性技能叫:

Skills = (SkillCollection)SkillCollection.Deser(
      Path.Combine(path, "Skills.xml"), 
      typeof(SkillCollection)); 

技能類:

public class Skill 
{ 
    //Cast: time it takes to cast it 
    [DataMember(Name = "Cast")] 
    public float Cast { get; set; } 

    //ReCast: cooldown period before player can cast it again 
    [DataMember(Name = "ReCast")] 
    public float ReCast { get; set; } 

    [DataMember(Name = "MPCost")] 
    public int MpCost { get; set; } 

    public Timer Timer { get; private set; } 
    public bool Ready { get; set; } 

    public Skill() 
    { 
     Ready = true; 

     Timer = new Timer { Interval = ReCast + 500, AutoReset = false }; 
     Timer.Elapsed += OnTimedEvent; 
    } 

    //Runs when recast is up 
    private void OnTimedEvent(object source, ElapsedEventArgs e) 
    { 
     Ready = true; 
    } 
} 

XML文件:

<Skills> 
    <Slash> 
    <Cast>0.00</Cast> 
    <ReCast>60.00</ReCast> 
    <MPCost>0</MPCost> 
    </Slash> 
    <Summon> 
    <Cast>5.98</Cast> 
    <ReCast>2.49</ReCast> 
    <MPCost>0</MPCost> 
    </Summon> 
</Skills> 

只是所以沒有混亂,我的目標是運行解串器,然後讓SkillCollection類包含兩個實例技能(斜線和召喚),並能夠通過他們的屬性單獨訪問它們。

感謝您的任何幫助/提示與調試。

+1

附加問題:1)屬性的順序是否有匹配的XML的順序? 2)如果XML中沒有所有塊的屬性會發生什麼(例如,XML有第三種技能,稱爲kick,但kick在SkillCollection中沒有屬性)。會導致問題嗎? 3)另一種方式如何(有些屬性在XML中沒有塊來匹配它)。這會是一個問題嗎?謝謝 – Anders 2014-09-21 16:16:00

+1

我認爲調試的第一步就是通過序列化程序運行你的對象,看看它產生了什麼XML。然後,您可以將它與您提供的XML進行比較。但是,'DataContractSerializer'不會是我的選擇。它有很多問題,例如[它需要在xml中按字母順序排列屬性](http://stackoverflow.com/questions/18463575/why-needs-datacontractserializer-alphabetically-sorted-xml)。改用'XmlSerializer'。 – 2014-09-21 17:27:04

+1

@mikez謝謝!按alpha排序並使用Magnus提供的代碼對問題進行排序。謝謝你們兩位! – Anders 2014-09-21 18:15:21

回答

0

Anders,

我最近做了一個類似的任務。看着你的代碼,你似乎設置了DataContract Name和Namespace錯誤。在Skill類和SkillCollection類之上,您需要指定:[DataContract(Name = "Skills", Namespace = "")]。這對序列化程序「允許」進入屬性至關重要。請記住,將它設置在SkillCollection類上方是不夠的。

編輯:我最初認爲你可以省略Namespace,但你不能。必須將其設置爲Namespace=""(在不指定XML中的名稱空間的情況下),或者指定名稱空間的情況下(如果您指定它)。

此外,辦法調試它是改變DESER方法是:

public static object Deserialize(string path, Type toType) 
    { 
     using (var sr = new FileStream(path, FileMode.Open)) 
     { 
      SkillCollection p = null; 
      XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(sr, new XmlDictionaryReaderQuotas()); 
      var serializer = new DataContractSerializer(toType); 

      while (reader.Read()) 
      { 
       switch (reader.NodeType) 
       { 
        case XmlNodeType.Element: 
         if (serializer.IsStartObject(reader)) 
         { 
          Console.WriteLine(@"Found the element"); 
          p = (SkillCollection)serializer.ReadObject(reader); 
          Console.WriteLine("{0} {1} id:{2}", 
           p.Slash.ToString(), p.Summon.ToString()); 
         } 
         Console.WriteLine(reader.Name); 
         break; 
       } 
      } 

      return p; 
     } 
    } 
+1

感謝您的編輯。按照最初的建議,我嘗試拋棄名稱空間,但使用您建議的調試代碼很明顯需要包含它。 – Anders 2014-09-21 18:12:53