C# - analyse des données formatées par json en hashtables imbriqués

j'essaie de travailler avec des données formatées json en C#, mais j'ai quelques problèmes pour déterminer la bonne façon d'aborder le problème. Mon problème est que les données formatées par json seront dans un format inconnu (je sais que cela semble étrange ... s'il vous plaît lire la suite). Fondamentalement, les données formatées par json seront une certaine collection de paires nom/valeur où les valeurs peuvent ou ne peuvent pas être des tableaux de paires nom/valeur imbriquées. Pour rendre les choses plus amusantes, l'imbrication des tableaux de couples nom/valeur peut continuer sur l'infini.

par exemple: J'ai peut-être des données qui ressemblent à ...

{
    "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"
        }
    }
}

malheureusement, je ne sais pas combien de nidification va se produire et techniquement Je ne sais pas quels noms/couples de valeur seront présents dans un message donné.

y a-t-il un mécanisme en C# qui me permettrait de facilement analyser ceci en un ensemble imbriqué de hastables?

j'aimerais faire quelque chose le long du les lignes de (notez que ce code n'est pas 100% correct syntaxiquement et de mieux se faire via la récursivité ... mais c'est l'idée).

Hashtable ht = [deserialize data method](jsonformattedstring);
foreach (Hashtable nested in ht)
{
    If (nested.count > 1)
        {
        Foreach (hashtable next in nested)
        …
        }
}
4
demandé sur BanksySan 2009-04-29 18:59:07

4 réponses

Je n'ai pas aimé le parsing. Net Json...il fait des choses étranges de temps en temps. J'ai passé à Json.NET , une bibliothèque open source. Il a un bel objet JObject qui fera ce que vous avez besoin.

3
répondu jvenema 2009-04-29 15:16:45

dans .NET, vous avez le JsonArray , qui vous permet de charger et analyser les données JSON. Il crée un tableau de JsonValue et il est complètement imbriqué basé sur les données JSON qu'il analyse.

si vous avez spécifiquement besoin de Hashtable, vous pouvez traduire les données de JsonArray, bien que Hastable soit tout sauf déprécié en faveur du dictionnaire.

Josh Holmes a un assez bon "getting started" post à propos de JSON dans .NET: http://www.joshholmes.com/blog/2009/01/20/PlayingWithJSON.aspx

4
répondu Brian Genisio 2009-04-29 15:13:41

vous pouvez regarder http://techblog.procurios.nl/k/n618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html il s'agit d'une simple bibliothèque qui analyse une chaîne JSON en Hashtables et en tableaux. Il peut également transformer ces structures en JSON à nouveau.

2
répondu Patrick van Bergen 2011-06-15 06:47:09

Voici une méthode que j'ai écrite en C# pour analyser JSON et retourner un dictionnaire. Bien sûr, il n'est pas approprié pour tous les cas d'utilisation, mais quelque chose comme cela vous donnera un beau passe-passe du 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;
    }
0
répondu Sam Grondahl 2012-08-14 20:02:50