6

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

例如:我可能有一些数据看起来像……</p>

{
    "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)
        …
        }
}
4

4 回答 4

4

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

如果您特别需要 Hashtable,则可以从 JsonArray 转换数据,尽管 Hastable 几乎已被弃用,取而代之的是 Dictionary。

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

于 2009-04-29T15:08:39.213 回答
4

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

于 2009-04-29T15:16:45.137 回答
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。

于 2011-06-15T06:47:09.367 回答
1

这是我用 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;
    }
于 2012-08-14T20:02:50.187 回答