C# - 将 json 格式的数据解析为嵌套的哈希表
Posted
技术标签:
【中文标题】C# - 将 json 格式的数据解析为嵌套的哈希表【英文标题】:C# - parsing json formatted data into nested hashtables 【发布时间】:2010-10-22 14:41:54 【问题描述】:我正在尝试在 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)
…
【问题讨论】:
【参考方案1】:我不喜欢 .Net Json 解析...它偶尔会做一些奇怪的事情。我已经切换到Json.NET,一个开源库。它有一个很好的 JObject 对象,可以满足您的需要。
【讨论】:
JSON.NET 运行良好(在花费大量时间处理其复杂性之后)。我唯一的批评是 JObject、JValue 和其他“较低级别”的对象没有很好的文档记录。感谢您为我指明正确的方向。 我和伤寒在同一条船上。您有解决原始问题的任何代码示例吗?显然伤寒想通了,但我还没有。【参考方案2】:在 .NET 中,您有 JsonArray,它允许您加载和解析 JSON 数据。它创建了一个 JsonValue 数组,并基于它解析的 JSON 数据完全嵌套。
如果你特别需要 Hashtable,你可以翻译 JsonArray 中的数据,尽管 Hastable 几乎不赞成使用 Dictionary。
Josh Holmes 有一篇关于 .NET 中 JSON 的非常好的“入门”文章: http://www.joshholmes.com/blog/2009/01/20/PlayingWithJSON.aspx
【讨论】:
我认为它只能在 Silverlight 中使用。【参考方案3】:你可能想看看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# 胜过承担依赖关系,或者与序列化类和迟钝的运行时结构混为一谈。如果您只想走一个结构,而不需要类的行为,那么这是您最好的解决方案。【参考方案4】:这是我用 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<string, string> jsonParse(string rawjson)
Dictionary<string, string> outdict = new Dictionary<string, string>();
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;
【讨论】:
以上是关于C# - 将 json 格式的数据解析为嵌套的哈希表的主要内容,如果未能解决你的问题,请参考以下文章
c# json数据解析——将字符串json格式数据转换成对象