En go el paquete estándar codificación/json expone json.Unmarshal función para analizar JSON.

Es posible deserializar la cadena JSON en un predefinidos struct, o el uso de la interface{} y repetir el resultado inesperado de datos JSON estructura.

Que dijo, yo no puedo analizar complejo JSON correctamente. Alguien me puede decir cómo conseguir esto?

 {
     "k1" : "v1", 
     "k2" : "v2", 
     "k3" : 10, 
     "result" : [
                 [
                 ["v4", v5, {"k11" : "v11", "k22" : "v22"}]
                 , ... , 
                 ["v4", v5, {"k33" : "v33", "k44" : "v44"}
                 ]
                 ], 
                 "v3"
                ] 
}
InformationsquelleAutor wells | 2015-05-20

3 Comentarios

  1. 34

    Citando JSON y Vaya:

    Sin conocer los datos de la estructura, podemos decodificar en una interfaz{} valor con Deserializar:

    b := []byte(`{
       "k1" : "v1", 
       "k3" : 10,
       result:["v4",12.3,{"k11" : "v11", "k22" : "v22"}]
    }`)
    var f interface{}
    err := json.Unmarshal(b, &f)

    En este punto, el valor de Ir en f sería un mapa cuyas claves son cadenas y cuyos valores en sí mismos son almacenados como vacía de valores de la interfaz:

    f = map[string]interface{}{
        "k1": "v1",
        "k3":  10,
        "result": []interface{}{
           "v4",
           12.3,
           map[string]interface{}{
               "k11":"v11",
               "k22":"v22",
           },
        },
    }

    Para acceder a estos datos, podemos utilizar un tipo de afirmación para acceder a f‘s subyacente mapa[cadena de]la interfaz{}:

    m := f.(map[string]interface{})

    Podemos recorrer el mapa con un rango de instrucción y el uso de un tipo de interruptor para acceder a sus valores como en sus tipos de hormigones:

    for k, v := range m {
        switch vv := v.(type) {
        case string:
            fmt.Println(k, "is string", vv)
        case int:
            fmt.Println(k, "is int", vv)
        case []interface{}:
            fmt.Println(k, "is an array:")
            for i, u := range vv {
                fmt.Println(i, u)
            }
        default:
            fmt.Println(k, "is of a type I don't know how to handle")
        }
    }

    De esta manera se puede trabajar con desconocidos de datos JSON, mientras que todavía goza de los beneficios de la seguridad de tipos.

    Obtener más información acerca de Ir y JSON se puede encontrar en el artículo original. He cambiado el código de fragmentos ligeramente a ser más similar a la de JSON en la pregunta.

    • muchas gracias, muy útil para mí.
    • var titular de la interfaz{} json.Deserializar(mensaje, &titular) retorno determineTypeHelper(titular.(mapa[cadena de]la interfaz{})) . iam haciendo esto y obteniendo el siguiente error??? la interfaz de conversión: la interfaz {} es nulo, no mapa[cadena de]la interfaz {}
    • Sólo quería mencionar, var f interface{}; err := yaml.Unmarshal(b, &f) también funciona con github.com/go-yaml/yaml.
    • También me sale el error «de la interfaz de conversión: la interfaz {} es nulo, no mapa[cadena de]la interfaz {}». Alguna idea?
    • la interfaz{} es nulo debido a que la cadena json no es válido. los resultados deben ser «resultados». Aquí está una zona de juegos con el código anterior ejemplo (usando el json de corrección): play.golang.org/p/RLodJLwy19
  2. 4

    Más recientemente, gjson ofrece una selección de propiedades en JSON

    k1 := gjson.Get(json, "k1")
    k33 : = gjson.Get(json, "result.#.#.k33")
    • No sabía acerca de esto, gracias! He actualizado mi post, como me ocurre a aprender más acerca de este material recientemente, la esperanza de que puede ser útil para usted también.
  3. 3

    El uso de la biblioteca estándar de encoding/json paquete

    He trabajado de JSON y Vaya artículo, y resultó que case int no funciona y necesita ser case float64 ahora, y hay un montón de anidación en el mundo real JSON.

    > go version
    go version go1.7.1 darwin/amd64

    También he mirado La decodificación JSON en Ir, pero no me ayuda mucho, ya que yo tenía que hacer proceduralrly traform en una serie de llamadas a mruby de unión, y el autor de ese artículo es feliz con Ir estructuras para la mayoría.

    Me he pasado un poco de tiempo jugando con esto y final de la iteración en función de dumper se veía así:

    func dumpJSON(v interface{}, kn string) {
        iterMap := func(x map[string]interface{}, root string) {
            var knf string
            if root == "root" {
                knf = "%q:%q"
            } else {
                knf = "%s:%q"
            }
            for k, v := range x {
                dumpJSON(v, fmt.Sprintf(knf, root, k))
            }
        }
    
        iterSlice := func(x []interface{}, root string) {
            var knf string
            if root == "root" {
                knf = "%q:[%d]"
            } else {
                knf = "%s:[%d]"
            }
            for k, v := range x {
                dumpJSON(v, fmt.Sprintf(knf, root, k))
            }
        }
    
        switch vv := v.(type) {
        case string:
            fmt.Printf("%s => (string) %q\n", kn, vv)
        case bool:
            fmt.Printf("%s => (bool) %v\n", kn, vv)
        case float64:
            fmt.Printf("%s => (float64) %f\n", kn, vv)
        case map[string]interface{}:
            fmt.Printf("%s => (map[string]interface{}) ...\n", kn)
            iterMap(vv, kn)
        case []interface{}:
            fmt.Printf("%s => ([]interface{}) ...\n", kn)
            iterSlice(vv, kn)
        default:
            fmt.Printf("%s => (unknown?) ...\n", kn)
        }
    }

    Con b ser un byte rebanada con un JSON que representa un array o un objeto en el nivel superior, se le puede llamar así:

    var f interface{}
    if err := json.Unmarshal(b, &f); err != nil {
        panic(err)
    }
    dumpJSON(f, "root")

    Espero que esto ayude, intenta el cumplimiento del programa aquí.

    El uso de otros paquetes de

    Yo recomendaría no hacerlo usted mismo, a menos que usted se siente que usted tiene que aprender cómo Van los tipos de trabajo y el uso de reflect te hace sentir como un maestro del universo (personalmente, reflect me conduce loco).

    Como @changingrainbows señaló a continuación, hay github.com/tidwall/gjson paquete, que parece envolver encoding/json y utiliza reflect. Yo no podría ser muy diferente de la github.com/mitchellh/reflectwalk, lo cual es bastante difícil de usar y funcionamiento interno son algo muy complicado.

    He utilizado github.com/buger/jsonparser más ampliamente en uno de mis proyectos, y también hay github.com/json-iterator/go, que no lo he probado aún, pero parece estar basado en github.com/buger/jsonparser y aparece para exponer enconding/jsoncompatible con la interfaz y se ha func Get(datos []bytes, ruta ...la interfaz{}) Cualquier así. Para el registro, Kubernetes proyecto ha cambiado recientemente a github.com/json-iterator/go.
    En mi proyecto, yo uso encoding/json así como github.com/buger/jsonparser, probablemente voy a cambiar a github.com/json-iterator/go cuando tengo tiempo. Voy a tratar de actualizar este post con más hallazgos.

Dejar respuesta

Please enter your comment!
Please enter your name here