Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#-将json格式的数据解析为嵌套哈希表_C#_Json_Hashtable - Fatal编程技术网

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

C#-将json格式的数据解析为嵌套哈希表,c#,json,hashtable,C#,Json,Hashtable,我正在尝试使用C#中的一些json格式的数据,但是,在确定解决问题的正确方法时遇到了一些问题。我的问题是json格式的数据将采用未知格式(我知道这听起来很奇怪……请继续阅读)。基本上,json格式的数据将是一些名称/值对的集合,其中的值可能是嵌套的名称/值对数组,也可能不是。为了让事情变得更有趣,名称/值对数组的嵌套可以无限期地继续 例如: 我可能有一些数据看起来像 { "1": { "1.1": { "1.1.1": "value1",

我正在尝试使用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%正确的,最好通过递归来完成……但这是一个好主意)

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

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

Josh Holmes有一篇关于.NET中JSON的非常好的“入门”帖子:
我不喜欢.Net Json解析…它偶尔会做一些奇怪的事情。我已经切换到开源库。它有一个很好的JObject对象,可以满足您的需要。

您可能想看看它是一个简单的库,可以将JSON字符串解析为哈希表和ArrayList。它还可以将这些结构再次转换为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<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;
    }
/*
*此方法以javascript函数返回的形式接收JSON
*stringify(Object)并返回字符串->字符串字典。
*当json的格式未知时,可以使用此方法。
*您可以在源代码中很容易地修改分隔符等
*(很抱歉,我没有抽象它——我有一个非常具体的用途)。
*/ 
公共静态字典jsonParse(字符串rawjson)
{
Dictionary outdict=新字典();
StringBuilder keybufferbuilder=新的StringBuilder();
StringBuilder valuebufferbuilder=新的StringBuilder();
StringReader bufferreader=新的StringReader(rawjson);
int s=0;
布尔读数=假;
bool inside_string=false;
bool reading_value=false;
//结束时中断(返回值-1)
而(s>=0)
{
s=bufferreader.Read();
//打开json
如果(!读取)
{
如果((char)s=='{'&&&!inside_string&&!reading)reading=true;
继续;
}
其他的
{
//如果我们找到一个报价,而我们还没有进入一个字符串,那么前进并进入其中
如果(!在字符串内)
{
//把这句话读过去
如果((char)s=='\'')内的字符串=true;
继续;
}
如果(在字符串内)
{
//如果我们到达绳子的末端
如果((char)s=='\'')
{
内部字符串=false;
s=bufferreader.Read();//前进指针
如果((char)s==':')
{
读取值=真;
继续;
}
如果(读取_值&&(字符)s==',')
{
//我们知道我们刚刚结束了这一行,所以把它放在我们的字典里
如果(!outdict.ContainsKey(keybufferbuilder.ToString()))outdict.Add(keybufferbuilder.ToString(),valuebufferbuilder.ToString());
//并清除缓冲区
keybufferbuilder.Clear();
valuebufferbuilder.Clear();
读取_值=错误;
}
如果(读取_值&&(char)s=='}')
{
//我们知道我们刚刚结束了这一行,所以把它放在我们的字典里
如果(!outdict.ContainsKey(keybufferbuilder.ToString()))outdict.Add(keybufferbuilder.ToString(),valuebufferbuilder.ToString());
//并清除缓冲区
keybufferbuilder.Clear();
valuebufferbuilder.Clear();
读取_值=错误;
阅读=错误;
打破
}
}
其他的
{
if(读取_值)
{
valuebufferbuilder.Append((char)s);
继续;
}
其他的
{
追加((char)s);
继续;
}
}
}
其他的
{
开关((字符)s)
{
案例“:”:
读取值=真;
打破
违约:
if(读取_值)
{
/*
     * 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;
    }