Pergunta

Eu estou tentando trabalhar com alguns JSON dados formatados em C #, mas, eu estou tendo alguns problemas em determinar a maneira correta de abordar o problema. Meu problema é que os dados JSON formatado será em um formato desconhecido (Eu sei que soa estranho ... por favor leia). Basicamente, os dados json formatado será alguns colecção de pares de nome / valor onde os valores podem ou não podem ser matrizes de pares de nome / valor aninhados. Para tornar as coisas mais divertido, o assentamento das nome / valor matrizes par pode continuar ad infinitum.

Por exemplo: Eu poderia ter alguns dados que se parece com ...

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

Infelizmente, eu não sei o quanto de nidificação vai ocorrer e tecnicamente eu não sei o nome / valor pares estará presente em qualquer mensagem.

Existe algum mecanismo suportado em C # que me permitirá facilmente analisar isso em um conjunto aninhado de hastables?

Eu gostaria de fazer algo ao longo das linhas (Nota este código não é 100% sintaticamente corretas e seria melhor feito através de recursão ... mas chegar a idéia do outro lado).

Hashtable ht = [deserialize data method](jsonformattedstring);
foreach (Hashtable nested in ht)
{
    If (nested.count > 1)
        {
        Foreach (hashtable next in nested)
        …
        }
}
Foi útil?

Solução

Eu não gostava da análise Net Json ... ele faz algumas coisas estranhas ocasionalmente. Eu mudei para Json.NET , uma biblioteca de código aberto. Tem um jobject objeto agradável que vai fazer o que você precisa.

Outras dicas

Em .NET, você tem a JsonArray , que lhe permite carregar e analisar os dados JSON. Ele cria uma matriz de JsonValue e é completamente aninhadas com base nos dados JSON ele analisa.

Se você especificamente precisa Hashtable, você poderia traduzir os dados de JsonArray, embora Hastable é tudo, mas depreciado em favor do dicionário.

Josh Holmes tem uma boa bastante "Getting Started" post sobre JSON no .NET: http://www.joshholmes.com/blog/2009/01/ 20 / PlayingWithJSON.aspx

Você pode querer olhar para http://techblog.procurios.nl/k/n618/news/view/14605/14863/How-do-I-write-my-own-parser-for- JSON.html é uma biblioteca simples que analisa uma cadeia JSON em Hashtables e ArrayLists. Ele também pode transformar estas estruturas em JSON novamente.

Aqui está um método que eu escrevi em C # para analisar JSON e retornar um dicionário. Claro que não é apropriado para todos os casos de uso, mas algo como isso vai lhe dar uma boa de uma passagem de análise do 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;
    }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top