2014-03-28 106 views
0

我有一個自定義的數據字符串,我從來沒有使用過。它看起來與JSON類似,但它有一個獨特的結構,我無法解決如何正確反序列化。自定義字符串反序列化

這裏是展示什麼我處理的一個簡單的模擬結構的示例串:

description=" 
has_table=TRUE 
scale=1.0 
apply_scale=FALSE 
custom_units=1 
style{ 
0{ 
    name="TestName1 
    description=" 
    color=-1006632961 
    size=0.5 
    adaptive=TRUE 
} 
1{ 
    name="TestName2 
    description=" 
    color=-1 
    size=0.75 
    adaptive=TRUE 
} 
2{ 
    name="TestName3 
    description=" 
    color=-1006632354 
    size=1.5 
    adaptive=FALSE 
} 
size_table{ 
0=0.0 
1=0.1 
2=0.2 
3=0.25 
10=0.35 
13=0.5 
17=0.75 
20=1.0 
21=1.25 
22=1.5 
} 

我一直在手動滾動我自己的類爲止。上面的字符串最終將反序列化到以下類中:

public class ExampleStyleList 
{ 
    public string Description {get; set;} 
    public bool HasTable {get; set;} 
    public double Scale {get; set;} 
    public bool ApplyScale {get; set;} 
    public int CustomUnits {get; set;} 
    public IList<double> Sizes {get; set;} 

    protected IList<ExampleStyle> InnerStyles {get; set;} 
} 

public class ExampleStyle 
{ 
    public string Name {get; set;} 
    public string Description {get; set;} 
    public System.Drawing.Color Color {get; set;} 
    public double Size {get; set;} 
    public bool Adaptive {get; set;} 
} 

現在我手動反序列化一切到我的類;一次讀一行,尋找括號,建立字典,尋找事物的靜態名稱。這非常醜陋,並且效率不高,更不用說可能會超級脆弱。我覺得我會先從這種奇怪的格式轉爲使用XML,然後我才能使用XMLSerializer,但我真的很空虛。

+1

添加你的類結構,我也會創建一個size_table類,因爲它會將你的尺寸鏈接到一個ID,而不是ILIST的雙打 – Schuere

回答

0

我最終只是手動模仿XML節點層次結構,並對結果非常滿意。一旦我將類設置爲從定製節點類繼承,實現反序列化就非常簡單。當我們遍歷線時,要麼向當前節點添加一個值,要麼正在構建一個子節點。反序列化是從內部構造函數調用的,所以這裏的遞歸可能乍看起來並不明顯。

public static void Deserialize(PiaNode node) 
    { 
     if (node == null) 
      throw new ArgumentNullException("Node"); 

     if (String.IsNullOrEmpty(node.InnerData)) 
      throw new ArgumentNullException("InnerData"); 

     var dataLines = node.InnerData.Split(new char[]{'\r', '\n'}, 
             StringSplitOptions.RemoveEmptyEntries); 

     for (int i = 0; i < dataLines.Length; i++) 
     { 
      var curLine = dataLines[i]; 
      if (curLine.Contains('=')) 
      { 
       var value = _getValue(curLine); 

       if (!node.Values.ContainsKey(value.Key)) 
        node.Values.Add(value.Key, value.Value); 
       else 
        node.Values[value.Key] = value.Value; 
      } 
      else if (curLine.Contains('{')) 
      { 
       var bracketCount = 1; 
       var nodeBuilder = new StringBuilder(); 
       var n = i + 1; 
       var subLine = string.Empty; 

       while (bracketCount != 0) 
       { 
        subLine = dataLines[n++]; 
        bracketCount += subLine.Contains('{') 
         ? 1 : subLine.Contains('}') 
         ? -1 : 0; 

        if (bracketCount != 0) 
         nodeBuilder.AppendLine(subLine); 
       } 

       var childNode = new PiaNode(nodeBuilder.ToString()) 
       { 
        NodeName = curLine.Trim().TrimEnd('{'), 
        Parent = node 
       }; 

       node.ChildNodes.Add(childNode); 
       i = n - 1; 
      } 
     } 
    } 

    public static KeyValuePair<string, string> _getValue(string valueString) 
    { 
     var prop = valueString.TrimEnd(new char[] {'\r', '\n'}).Split('='); 
     return new KeyValuePair<string,string>(prop[0].Trim(), prop[1].TrimStart('\"')); 
    } 

而不是試圖並設置節點繼承類的反序列化過程中的屬性(我在做之前),我只是鏈接的制定者/屬性直奔這是反序列化過程中人口字典的干將。