2012-01-23 47 views
5

我有一個JSON結構,我想用JSON.NET手動解析到POCO對象。如何使用JSON.NET迭代嵌套字典?

JSON結構是一堆嵌套字典......根字典包含類別,下一級包含這些類別中的產品,最後一級包含這些產品的版本。

{ 
     "category-1": { 
      "product-1": { 
       "product-version-1": { 
        "id":1, 
        ... 
       } 
      } 
     }, 
     "category-2": { 
      "product-2": { 
       "product-version-2": { 
        "id":2, 
        ... 
       } 
      }, 
      "product-3": { 
       "product-version-3": { 
        "id":3, 
        ... 
       } 
      } 
     } 
} 

我想分析這種結構,牢記所有字典的鍵不提前知道給我。

這是我編寫的代碼(一旦它工作,我將轉換爲LINQ ...) - 我期望這可以與一些嵌套循環一起工作,但顯然JTokens和JObjects不能以這種方式工作我以爲... Id始終爲空。

var productsJObject = JObject.Parse(result.Content.ReadAsStringAsync().Result); 

foreach (var category in productsJObject) 
{ 
    foreach (var product in category.Value) 
    { 
     foreach (var version in product) 
     { 
      var poco = new Poco 
         { 
          Id = version.SelectToken("id").ToString() 
         }; 
     } 
    } 
} 

所以我的問題,我如何迭代使用JSON.Net的嵌套字典?

回答

6

發現這個問題試圖找出如何解析JSON.NET在C#中。希望我的回答會幫助別人...

我寫了這段代碼來幫助我解析一個隨機的JSON對象並分析結構。這有點粗糙,可能無法處理所有情況,但它的確有用。現在它只是在字典中存儲位置,但它應該很容易地看到它在做什麼並修改它以做你想做的事情:

static void Main(string[] args) 
{ 
    Dictionary<string, string> nodes = new Dictionary<string, string>(); 

    // put your JSON object here 
    JObject rootObject = JObject.Parse("{\"world\": {\"hello\": \"woo\", \"foo\": \"bar\", \"arr\": [\"one\", \"two\"]}}"); 

    ParseJson(rootObject, nodes); 

    // nodes dictionary contains xpath-like node locations 
    Debug.WriteLine(""); 
    Debug.WriteLine("JSON:"); 
    foreach (string key in nodes.Keys) 
    { 
     Debug.WriteLine(key + " = " + nodes[key]); 
    } 
} 

/// <summary> 
/// Parse a JSON object and return it as a dictionary of strings with keys showing the heirarchy. 
/// </summary> 
/// <param name="token"></param> 
/// <param name="nodes"></param> 
/// <param name="parentLocation"></param> 
/// <returns></returns> 
public static bool ParseJson(JToken token, Dictionary<string, string> nodes, string parentLocation = "") 
{ 
    if (token.HasValues) 
    { 
     foreach (JToken child in token.Children()) 
     { 
      if (token.Type == JTokenType.Property) 
       parentLocation += "/" + ((JProperty)token).Name; 
      ParseJson(child, nodes, parentLocation); 
     } 

     // we are done parsing and this is a parent node 
     return true; 
    } 
    else 
    { 
     // leaf of the tree 
     if (nodes.ContainsKey(parentLocation)) 
     { 
      // this was an array 
      nodes[parentLocation] += "|" + token.ToString(); 
     } 
     else 
     { 
      // this was a single property 
      nodes.Add(parentLocation, token.ToString()); 
     } 

     return false; 
    } 
}