2012-01-23 43 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; 
    } 
}