C# – 将json格式的数据解析为嵌套的哈希表

我正在尝试使用C#中的一些json格式化数据,但是,我在确定解决问题的正确方法时遇到了一些问题。 我的问题是json格式的数据将采用未知格式(我知道这听起来很奇怪……请继续阅读)。 基本上,json格式的数据将是一些名称/值对的集合,其中值可能是也可能不是嵌套名称/值对的数组。 为了使事情变得更有趣,名称/值对数组的嵌套可以无限制地继续。

例如:我可能有一些看起来像……的数据

{ "1": { "1.1": { "1.1.1": "value1", "1.1.2": "value2", "1.1.3": "value3" }, "1.2": "value4", "1.3": { "1.3.1": { "1.3.1.1": "value5", "1.3.1.2": "value6" }, "1.3.1.2": "value7", "1.3.1.3": "value8" } } } 

不幸的是,我不知道将要发生多少嵌套,从技术上讲,我不知道在任何给定的消息中将出现什么名称/值对。

C#中是否有任何支持的机制可以让我轻松地将其解析为嵌套的hastables集合?

我想做一些事情(注意这段代码不是100%语法正确,最好通过递归来完成……但是它的想法是完整的)。

 Hashtable ht = [deserialize data method](jsonformattedstring); foreach (Hashtable nested in ht) { If (nested.count > 1) { Foreach (hashtable next in nested) … } } 

我不喜欢.Net Json解析…它偶尔会做一些奇怪的事情。 我已经切换到开源库Json.NET了。 它有一个很好的JObject对象,可以满足你的需要。

在.NET中,您有JsonArray ,它允许您加载和解析JSON数据。 它创建了一个JsonValue数组,它完全嵌套在它解析的JSON数据上。

如果你特别需要Hashtable,你可以从JsonArray转换数据,虽然Hastable几乎全部被弃用而不支持Dictionary。

Josh Holmes在.NET中有一篇关于JSON的非常好的“入门”post: http : //www.joshholmes.com/blog/2009/01/20/PlayingWithJSON.aspx

您可以查看http://techblog.procurios.nl/k/n618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html这是一个将JSON字符串解析为Hashtables和ArrayLists的简单库。 它还可以将这些结构再次转换为JSON。

这是我在C#中编写的一种解析JSON并返回字典的方法。 当然它并不适用于所有用例,但是像这样的东西会给你一个很好的一次性解析JSON:

 /* * This method takes in JSON in the form returned by javascript's * JSON.stringify(Object) and returns a string->string dictionary. * This method may be of use when the format of the json is unknown. * You can modify the delimiters, etc pretty easily in the source * (sorry I didn't abstract it--I have a very specific use). */ public static Dictionary jsonParse(string rawjson) { Dictionary outdict = new Dictionary(); StringBuilder keybufferbuilder = new StringBuilder(); StringBuilder valuebufferbuilder = new StringBuilder(); StringReader bufferreader = new StringReader(rawjson); int s = 0; bool reading = false; bool inside_string = false; bool reading_value = false; //break at end (returns -1) while (s >= 0) { s = bufferreader.Read(); //opening of json if (!reading) { if ((char)s == '{' && !inside_string && !reading) reading = true; continue; } else { //if we find a quote and we are not yet inside a string, advance and get inside if (!inside_string) { //read past the quote if ((char)s == '\"') inside_string = true; continue; } if (inside_string) { //if we reached the end of the string if ((char)s == '\"') { inside_string = false; s = bufferreader.Read(); //advance pointer if ((char)s == ':') { reading_value = true; continue; } if (reading_value && (char)s == ',') { //we know we just ended the line, so put itin our dictionary if (!outdict.ContainsKey(keybufferbuilder.ToString())) outdict.Add(keybufferbuilder.ToString(), valuebufferbuilder.ToString()); //and clear the buffers keybufferbuilder.Clear(); valuebufferbuilder.Clear(); reading_value = false; } if (reading_value && (char)s == '}') { //we know we just ended the line, so put itin our dictionary if (!outdict.ContainsKey(keybufferbuilder.ToString())) outdict.Add(keybufferbuilder.ToString(), valuebufferbuilder.ToString()); //and clear the buffers keybufferbuilder.Clear(); valuebufferbuilder.Clear(); reading_value = false; reading = false; break; } } else { if (reading_value) { valuebufferbuilder.Append((char)s); continue; } else { keybufferbuilder.Append((char)s); continue; } } } else { switch ((char)s) { case ':': reading_value = true; break; default: if (reading_value) { valuebufferbuilder.Append((char)s); } else { keybufferbuilder.Append((char)s); } break; } } } } return outdict; }