我正在尝试使用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)
…
}
}
答案 0 :(得分:4)
在.NET中,您拥有JsonArray,它允许您加载和解析JSON数据。它创建了一个JsonValue数组,它根据它解析的JSON数据完全嵌套。
如果你特别需要Hashtable,你可以从JsonArray转换数据,虽然Hastable几乎全部被弃用而不支持Dictionary。
Josh Holmes在.NET中有一篇关于JSON的非常好的“入门”帖子: http://www.joshholmes.com/blog/2009/01/20/PlayingWithJSON.aspx
答案 1 :(得分:3)
我不喜欢.Net Json解析...它偶尔会做一些奇怪的事情。我已切换到开源库Json.NET。它有一个很好的JObject对象,可以满足您的需求。
答案 2 :(得分:2)
您可能需要查看http://techblog.procurios.nl/k/n618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html这是一个简单的库,它将JSON字符串解析为Hashtables和ArrayLists。它还可以将这些结构再次转换为JSON。
答案 3 :(得分:0)
这是我在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;
}