2014-03-28 101 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('\"')); 
    } 

而不是试图并设置节点继承类的反序列化过程中的属性(我在做之前),我只是链接的制定者/属性直奔这是反序列化过程中人口字典的干将。