¿Alguien sabe de una forma sencilla a pretty-print salida JSON en Ir?

El stock http://golang.org/pkg/encoding/json/ paquete no parece incluir la funcionalidad de este (EDIT: sí, ver aceptado respuesta) y una rápida en google y no aparece nada obvio.

Usos estoy buscando son ambos bastante-imprimir el resultado de json.Marshal y sólo el formato de una cadena completa de JSON desde cualquier lugar, así que es más fácil de leer para fines de depuración.

  • Advertencia: en mis experimentos, en JSON diccionarios de las cadenas de índices deben estar entre paréntesis. Así, {name: "value"} no estar bien, a pesar de que la mayoría de la intérprete de Javascript utiliza. Sólo {"name": "value"} va a trabajar con JSON funciones de la biblioteca.
  • Creo que estás confundiendo JavaScript literal de la sintaxis JSON adecuada. El JSON spec (json.org) indica claramente que sólo los literales de cadena son permitidos (en el sentido que necesita comillas), mientras JS objeto lenguaje de sintaxis no tiene esa restricción. El Ir a la biblioteca es la siguiente especificación.
InformationsquelleAutor Brad Peabody | 2013-09-26

9 Comentarios

  1. 233

    Por pretty-print, supongo que te refieres a la sangría, como así

    {
        "data": 1234
    }

    lugar de

    {"data":1234}

    La manera más fácil de hacer esto es con MarshalIndent, que le permiten especificar cómo desea que se aplica sangría a través de la indent argumento. Por lo tanto, json.MarshalIndent(data, "", " ") bastante-imprimir con cuatro espacios de sangría.

    • De niza. Así: play.golang.org/p/6jHI-MRx0z
    • Sí, que se parece a la cosa ya está construido, sólo la izquierda es incluir la palabra clave «pretty-print» en el paquete doc por lo que el tipo de al lado, la búsqueda, la encuentra. (Voy a dejar un comentario nota para el departamento de comercio de los mantenedores.) Tks!
    • json.MarshalIndent(data, "", "\t") si quieres pestañas.
    • json.MarshalIndent(data, "", "🐱") si desea gatos. lo siento
    • El gato sangría de vino en la mano
    • gracias. Hizo que mi día.

  2. 60

    La aceptada respuesta es grande si usted tiene un objeto que quieres convertir en JSON. La pregunta también se menciona bastante a la impresión de cualquier cadena JSON, y eso es lo que yo estaba tratando de hacer. Yo sólo quería bastante-registro de algunos JSON de una solicitud POST (específicamente un CSP violación informe).

    Utilizar MarshalIndent, tendría que Unmarshal en un objeto. Si usted necesita eso, ir a por ello, pero yo no. Si usted sólo necesita bastante-imprimir una matriz de bytes, llanura Guión es tu amigo.

    He aquí lo que terminó con:

    import (
        "bytes"
        "encoding/json"
        "log"
        "net/http"
    )
    
    func HandleCSPViolationRequest(w http.ResponseWriter, req *http.Request) {
        body := App.MustReadBody(req, w)
        if body == nil {
            return
        }
    
        var prettyJSON bytes.Buffer
        error := json.Indent(&prettyJSON, body, "", "\t")
        if error != nil {
            log.Println("JSON parse error: ", error)
            App.BadRequest(w)
            return
        }
    
        log.Println("CSP Violation:", string(prettyJSON.Bytes()))
    }
  3. 36

    Para el mejor uso de la memoria, supongo que esto es mejor:

    var out io.Writer
    enc := json.NewEncoder(out)
    enc.SetIndent("", "    ")
    if err := enc.Encode(data); err != nil {
        panic(err)
    }
    • Hizo SetIndent añadido recientemente? Es esencialmente desconocido para la mayoría.
    • nombre Indent) al parecer fue agregado en Marzo de 2016 y publicado en Ir a 1,7, que fue de aproximadamente 3 años después de esta pregunta fue originalmente preguntó: github.com/golang/go/commit/… github.com/golang/go/commit/…
  4. 13

    Editar Mirando hacia atrás, esto no es idiomático-Ir. Pequeñas funciones auxiliares como esto agregar un paso adicional de complejidad. En general, la filosofía prefiere incluyen los 3 simples líneas más de 1 complicada línea.


    Como @robyoder mencionado, json.Indent es el camino a seguir. Pensé en añadir este pequeño prettyprint función:

    package main
    
    import (
        "bytes"
        "encoding/json"
        "fmt"
    )
    
    //dont do this, see above edit
    func prettyprint(b []byte) ([]byte, error) {
        var out bytes.Buffer
        err := json.Indent(&out, b, "", "  ")
        return out.Bytes(), err
    }
    
    func main() {
        b := []byte(`{"hello": "123"}`)
        b, _ = prettyprint(b)
        fmt.Printf("%s", b)
    }

    https://go-sandbox.com/#/R4LWpkkHIN o http://play.golang.org/p/R4LWpkkHIN

  5. 11

    Estaba frustrado por la falta de una rápida, de alta calidad para el mariscal de JSON a un coloreada cadena en Ir, así que escribí mi propio contador de referencias llamado ColorJSON.

    Con él, usted puede fácilmente producir una salida como esta con muy poco código:

    ¿Cómo puedo pretty-print JSON usando Ir?

    package main
    
    import (
        "fmt"
        "github.com/TylerBrock/colorjson"
        "encoding/json"
    )
    
    func main() {
        str := `{
          "str": "foo",
          "num": 100,
          "bool": false,
          "null": null,
          "array": ["foo", "bar", "baz"],
          "obj": { "a": 1, "b": 2 }
        }`
    
        var obj map[string]interface{}
        json.Unmarshal([]byte(str), &obj)
    
        //Make a custom formatter with indent set
        f := colorjson.NewFormatter()
        f.Indent = 4
    
        //Marshall the Colorized JSON
        s, _ := f.Marshal(obj)
        fmt.Println(string(s))
    }

    Estoy escribiendo la documentación de ahora, pero yo estaba emocionada de compartir mi solución.

  6. 6

    Aquí es lo que yo uso. Si se produce un error bastante imprimir el JSON que sólo devuelve la cadena original. Útil para la impresión de las respuestas HTTP debe contienen JSON.

    import (
        "encoding/json"
        "bytes"
    )
    
    func jsonPrettyPrint(in string) string {
        var out bytes.Buffer
        err := json.Indent(&out, []byte(in), "", "\t")
        if err != nil {
            return in
        }
        return out.String()
    }
  7. 5

    Aquí está mi solución:

    import (
        "bytes"
        "encoding/json"
    )
    
    const (
        empty = ""
        tab   = "\t"
    )
    
    func PrettyJson(data interface{}) (string, error) {
        buffer := new(bytes.Buffer)
        encoder := json.NewEncoder(buffer)
        encoder.SetIndent(empty, tab)
    
        err := encoder.Encode(data)
        if err != nil {
           return empty, err
        }
        return buffer.String(), nil
    }
  8. 2

    Un simple fuera de la plataforma bastante impresora en Ir. Uno puede compilarlo a un binario a través de:

    go build -o jsonformat jsonformat.go

    Se lee de la entrada estándar, escribe a la salida estándar y permiten establecer sangría:

    package main
    
    import (
        "bytes"
        "encoding/json"
        "flag"
        "fmt"
        "io/ioutil"
        "os"
    )
    
    func main() {
        indent := flag.String("indent", "  ", "indentation string/character for formatter")
        flag.Parse()
        src, err := ioutil.ReadAll(os.Stdin)
        if err != nil {
            fmt.Fprintf(os.Stderr, "problem reading: %s", err)
            os.Exit(1)
        }
    
        dst := &bytes.Buffer{}
        if err := json.Indent(dst, src, "", *indent); err != nil {
            fmt.Fprintf(os.Stderr, "problem formatting: %s", err)
            os.Exit(1)
        }
        if _, err = dst.WriteTo(os.Stdout); err != nil {
            fmt.Fprintf(os.Stderr, "problem writing: %s", err)
            os.Exit(1)
        }
    }

    Permite ejecutar un golpe de comandos como:

    cat myfile | jsonformat | grep "key"
  9. 1

    soy una clase de nuevo para ir, pero esto es lo que he reunido hasta ahora:

    package srf
    
    import (
        "bytes"
        "encoding/json"
        "os"
    )
    
    func WriteDataToFileAsJSON(data interface{}, filedir string) (int, error) {
        //write data as buffer to json encoder
        buffer := new(bytes.Buffer)
        encoder := json.NewEncoder(buffer)
        encoder.SetIndent("", "\t")
    
        err := encoder.Encode(data)
        if err != nil {
            return 0, err
        }
        file, err := os.OpenFile(filedir, os.O_RDWR|os.O_CREATE, 0755)
        if err != nil {
            return 0, err
        }
        n, err := file.Write(buffer.Bytes())
        if err != nil {
            return 0, err
        }
        return n, nil
    }

    Esta es la ejecución de la función, y sólo estándar

    b, _ := json.MarshalIndent(SomeType, "", "\t")

    Código:

    package main
    
    import (
        "encoding/json"
        "fmt"
        "io/ioutil"
        "log"
    
        minerals "./minerals"
        srf "./srf"
    )
    
    func main() {
    
        //array of Test struct
        var SomeType [10]minerals.Test
    
        //Create 10 units of some random data to write
        for a := 0; a < 10; a++ {
            SomeType[a] = minerals.Test{
                Name:   "Rand",
                Id:     123,
                A:      "desc",
                Num:    999,
                Link:   "somelink",
                People: []string{"John Doe", "Aby Daby"},
            }
        }
    
        //writes aditional data to existing file, or creates a new file
        n, err := srf.WriteDataToFileAsJSON(SomeType, "test2.json")
        if err != nil {
            log.Fatal(err)
        }
        fmt.Println("srf printed ", n, " bytes to ", "test2.json")
    
        //overrides previous file
        b, _ := json.MarshalIndent(SomeType, "", "\t")
        ioutil.WriteFile("test.json", b, 0644)
    
    }

Dejar respuesta

Please enter your comment!
Please enter your name here