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 réponses
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
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.
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;
}