README

Gabs

Gabs is a small utility for dealing with dynamic or unknown JSON structures in golang. It's pretty much just a helpful wrapper around the golang json.Marshal/json.Unmarshal behaviour and map[string]interface{} objects. It does nothing spectacular except for being fabulous.

https://godoc.org/github.com/Jeffail/gabs

Install

go get github.com/Jeffail/gabs

Use

Parsing and searching JSON

jsonParsed, err := gabs.ParseJSON([]byte(`{
	"outter":{
		"inner":{
			"value1":10,
			"value2":22
		},
		"alsoInner":{
			"value1":20,
			"array1":[
				30, 40
			]
		}
	}
}`))

var value float64
var ok bool

value, ok = jsonParsed.Path("outter.inner.value1").Data().(float64)
// value == 10.0, ok == true

value, ok = jsonParsed.Search("outter", "inner", "value1").Data().(float64)
// value == 10.0, ok == true

gObj, err := jsonParsed.JSONPointer("/outter/alsoInner/array1/1")
if err != nil {
	panic(err)
}
value, ok = gObj.Data().(float64)
// value == 40.0, ok == true

value, ok = jsonParsed.Path("does.not.exist").Data().(float64)
// value == 0.0, ok == false

exists := jsonParsed.Exists("outter", "inner", "value1")
// exists == true

exists := jsonParsed.ExistsP("does.not.exist")
// exists == false

Iterating objects

jsonParsed, _ := gabs.ParseJSON([]byte(`{"object":{ "first": 1, "second": 2, "third": 3 }}`))

// S is shorthand for Search
children, _ := jsonParsed.S("object").ChildrenMap()
for key, child := range children {
	fmt.Printf("key: %v, value: %v\n", key, child.Data().(string))
}

Iterating arrays

jsonParsed, err := gabs.ParseJSON([]byte(`{"array":[ "first", "second", "third" ]}`))
if err != nil {
	panic(err)
}

// S is shorthand for Search
children, err := jsonParsed.S("array").Children()
if err != nil {
	panic(err)
}

for _, child := range children {
	fmt.Println(child.Data().(string))
}

Will print:

first
second
third

Children() will return all children of an array in order. This also works on objects, however, the children will be returned in a random order.

Searching through arrays

If your JSON structure contains arrays you can still search the fields of the objects within the array, this returns a JSON array containing the results for each element.

jsonParsed, err := gabs.ParseJSON([]byte(`{"array":[ {"value":1}, {"value":2}, {"value":3} ]}`))
if err != nil {
	panic(err)
}
fmt.Println(jsonParsed.Path("array.value").String())

Will print:

[1,2,3]

Generating JSON

jsonObj := gabs.New()
// or gabs.Consume(jsonObject) to work on an existing map[string]interface{}

jsonObj.Set(10, "outter", "inner", "value")
jsonObj.SetP(20, "outter.inner.value2")
jsonObj.Set(30, "outter", "inner2", "value3")

fmt.Println(jsonObj.String())

Will print:

{"outter":{"inner":{"value":10,"value2":20},"inner2":{"value3":30}}}

To pretty-print:

fmt.Println(jsonObj.StringIndent("", "  "))

Will print:

{
  "outter": {
    "inner": {
      "value": 10,
      "value2": 20
    },
    "inner2": {
      "value3": 30
    }
  }
}

Generating Arrays

jsonObj := gabs.New()

jsonObj.Array("foo", "array")
// Or .ArrayP("foo.array")

jsonObj.ArrayAppend(10, "foo", "array")
jsonObj.ArrayAppend(20, "foo", "array")
jsonObj.ArrayAppend(30, "foo", "array")

fmt.Println(jsonObj.String())

Will print:

{"foo":{"array":[10,20,30]}}

Working with arrays by index:

jsonObj := gabs.New()

// Create an array with the length of 3
jsonObj.ArrayOfSize(3, "foo")

jsonObj.S("foo").SetIndex("test1", 0)
jsonObj.S("foo").SetIndex("test2", 1)

// Create an embedded array with the length of 3
jsonObj.S("foo").ArrayOfSizeI(3, 2)

jsonObj.S("foo").Index(2).SetIndex(1, 0)
jsonObj.S("foo").Index(2).SetIndex(2, 1)
jsonObj.S("foo").Index(2).SetIndex(3, 2)

fmt.Println(jsonObj.String())

Will print:

{"foo":["test1","test2",[1,2,3]]}

Converting back to JSON

This is the easiest part:

jsonParsedObj, _ := gabs.ParseJSON([]byte(`{
	"outter":{
		"values":{
			"first":10,
			"second":11
		}
	},
	"outter2":"hello world"
}`))

jsonOutput := jsonParsedObj.String()
// Becomes `{"outter":{"values":{"first":10,"second":11}},"outter2":"hello world"}`

And to serialize a specific segment is as simple as:

jsonParsedObj := gabs.ParseJSON([]byte(`{
	"outter":{
		"values":{
			"first":10,
			"second":11
		}
	},
	"outter2":"hello world"
}`))

jsonOutput := jsonParsedObj.Search("outter").String()
// Becomes `{"values":{"first":10,"second":11}}`

Merge two containers

You can merge a JSON structure into an existing one, where collisions will be converted into a JSON array.

jsonParsed1, _ := ParseJSON([]byte(`{"outter": {"value1": "one"}}`))
jsonParsed2, _ := ParseJSON([]byte(`{"outter": {"inner": {"value3": "three"}}, "outter2": {"value2": "two"}}`))

jsonParsed1.Merge(jsonParsed2)
// Becomes `{"outter":{"inner":{"value3":"three"},"value1":"one"},"outter2":{"value2":"two"}}`

Arrays are merged:

jsonParsed1, _ := ParseJSON([]byte(`{"array": ["one"]}`))
jsonParsed2, _ := ParseJSON([]byte(`{"array": ["two"]}`))

jsonParsed1.Merge(jsonParsed2)
// Becomes `{"array":["one", "two"]}`

Parsing Numbers

Gabs uses the json package under the bonnet, which by default will parse all number values into float64. If you need to parse Int values then you should use a json.Decoder (https://golang.org/pkg/encoding/json/#Decoder):

sample := []byte(`{"test":{"int":10, "float":6.66}}`)
dec := json.NewDecoder(bytes.NewReader(sample))
dec.UseNumber()

val, err := gabs.ParseJSONDecoder(dec)
if err != nil {
    t.Errorf("Failed to parse: %v", err)
    return
}

intValue, err := val.Path("test.int").Data().(json.Number).Int64()
Expand ▾ Collapse ▴

Documentation

Overview

    Package gabs implements a simplified wrapper around creating and parsing unknown or dynamic JSON.

    Index

    Constants

    This section is empty.

    Variables

    View Source
    var (
    	// ErrOutOfBounds indicates an index was out of bounds.
    	ErrOutOfBounds = errors.New("out of bounds")
    
    	// ErrNotObjOrArray is returned when a target is not an object or array type
    	// but needs to be for the intended operation.
    	ErrNotObjOrArray = errors.New("not an object or array")
    
    	// ErrNotObj is returned when a target is not an object but needs to be for
    	// the intended operation.
    	ErrNotObj = errors.New("not an object")
    
    	// ErrNotArray is returned when a target is not an array but needs to be for
    	// the intended operation.
    	ErrNotArray = errors.New("not an array")
    
    	// ErrPathCollision is returned when creating a path failed because an
    	// element collided with an existing value.
    	ErrPathCollision = errors.New("encountered value collision whilst building path")
    
    	// ErrInvalidInputObj is returned when the input value was not a
    	// map[string]interface{}.
    	ErrInvalidInputObj = errors.New("invalid input object")
    
    	// ErrInvalidInputText is returned when the input data could not be parsed.
    	ErrInvalidInputText = errors.New("input text could not be parsed")
    
    	// ErrInvalidPath is returned when the filepath was not valid.
    	ErrInvalidPath = errors.New("invalid file path")
    
    	// ErrInvalidBuffer is returned when the input buffer contained an invalid
    	// JSON string.
    	ErrInvalidBuffer = errors.New("input buffer contained invalid JSON")
    )

    Functions

    This section is empty.

    Types

    type Container

    type Container struct {
    	// contains filtered or unexported fields
    }

      Container references a specific element within a JSON structure.

      func Consume

      func Consume(root interface{}) (*Container, error)

        Consume an already unmarshalled JSON object (or a new map[string]interface{}) into a *Container.

        func New

        func New() *Container

          New creates a new gabs JSON object.

          func ParseJSON

          func ParseJSON(sample []byte) (*Container, error)

            ParseJSON unmarshals a JSON byte slice into a *Container.

            func ParseJSONBuffer

            func ParseJSONBuffer(buffer io.Reader) (*Container, error)

              ParseJSONBuffer reads a buffer and unmarshals the contents into a *Container.

              func ParseJSONDecoder

              func ParseJSONDecoder(decoder *json.Decoder) (*Container, error)

                ParseJSONDecoder applies a json.Decoder to a *Container.

                func ParseJSONFile

                func ParseJSONFile(path string) (*Container, error)

                  ParseJSONFile reads a file and unmarshals the contents into a *Container.

                  func (*Container) Array

                  func (g *Container) Array(path ...string) (*Container, error)

                    Array creates a new JSON array at a path. Returns an error if the path contains a collision with a non object type.

                    func (*Container) ArrayAppend

                    func (g *Container) ArrayAppend(value interface{}, path ...string) error

                      ArrayAppend attempts to append a value onto a JSON array at a path. If the target is not a JSON array then it will be converted into one, with its original contents set to the first element of the array.

                      func (*Container) ArrayAppendP

                      func (g *Container) ArrayAppendP(value interface{}, path string) error

                        ArrayAppendP attempts to append a value onto a JSON array at a path using dot notation. If the target is not a JSON array then it will be converted into one, with its original contents set to the first element of the array.

                        func (*Container) ArrayCount

                        func (g *Container) ArrayCount(path ...string) (int, error)

                          ArrayCount counts the number of elements in a JSON array at a path.

                          func (*Container) ArrayCountP

                          func (g *Container) ArrayCountP(path string) (int, error)

                            ArrayCountP counts the number of elements in a JSON array at a path using dot notation.

                            func (*Container) ArrayElement

                            func (g *Container) ArrayElement(index int, path ...string) (*Container, error)

                              ArrayElement attempts to access an element by an index from a JSON array at a path.

                              func (*Container) ArrayElementP

                              func (g *Container) ArrayElementP(index int, path string) (*Container, error)

                                ArrayElementP attempts to access an element by an index from a JSON array at a path using dot notation.

                                func (*Container) ArrayI

                                func (g *Container) ArrayI(index int) (*Container, error)

                                  ArrayI creates a new JSON array within an array at an index. Returns an error if the element is not an array or the index is out of bounds.

                                  func (*Container) ArrayOfSize

                                  func (g *Container) ArrayOfSize(size int, path ...string) (*Container, error)

                                    ArrayOfSize creates a new JSON array of a particular size at a path. Returns an error if the path contains a collision with a non object type.

                                    func (*Container) ArrayOfSizeI

                                    func (g *Container) ArrayOfSizeI(size, index int) (*Container, error)

                                      ArrayOfSizeI create a new JSON array of a particular size within an array at an index. Returns an error if the element is not an array or the index is out of bounds.

                                      func (*Container) ArrayOfSizeP

                                      func (g *Container) ArrayOfSizeP(size int, path string) (*Container, error)

                                        ArrayOfSizeP creates a new JSON array of a particular size at a path using dot notation. Returns an error if the path contains a collision with a non object type.

                                        func (*Container) ArrayP

                                        func (g *Container) ArrayP(path string) (*Container, error)

                                          ArrayP creates a new JSON array at a path using dot notation. Returns an error if the path contains a collision with a non object type.

                                          func (*Container) ArrayRemove

                                          func (g *Container) ArrayRemove(index int, path ...string) error

                                            ArrayRemove attempts to remove an element identified by an index from a JSON array at a path.

                                            func (*Container) ArrayRemoveP

                                            func (g *Container) ArrayRemoveP(index int, path string) error

                                              ArrayRemoveP attempts to remove an element identified by an index from a JSON array at a path using dot notation.

                                              func (*Container) Bytes

                                              func (g *Container) Bytes() []byte

                                                Bytes marshals an element to a JSON []byte blob.

                                                func (*Container) BytesIndent

                                                func (g *Container) BytesIndent(prefix string, indent string) []byte

                                                  BytesIndent marshals an element to a JSON []byte blob formatted with a prefix and indent string.

                                                  func (*Container) Children

                                                  func (g *Container) Children() ([]*Container, error)

                                                    Children returns a slice of all children of an array element. This also works for objects, however, the children returned for an object will be in a random order and you lose the names of the returned objects this way.

                                                    func (*Container) ChildrenMap

                                                    func (g *Container) ChildrenMap() (map[string]*Container, error)

                                                      ChildrenMap returns a map of all the children of an object element.

                                                      func (*Container) Data

                                                      func (g *Container) Data() interface{}

                                                        Data returns the underlying interface{} of the target element in the JSON structure.

                                                        func (*Container) Delete

                                                        func (g *Container) Delete(path ...string) error

                                                          Delete an element at a path, an error is returned if the element does not exist.

                                                          func (*Container) DeleteP

                                                          func (g *Container) DeleteP(path string) error

                                                            DeleteP deletes an element at a path using dot notation, an error is returned if the element does not exist.

                                                            func (*Container) EncodeJSON

                                                            func (g *Container) EncodeJSON(encodeOpts ...EncodeOpt) []byte

                                                              EncodeJSON marshals an element to a JSON formatted []byte using a variant list of modifier functions for the encoder being used. Functions for modifying the output are prefixed with EncodeOpt, e.g. EncodeOptHTMLEscape.

                                                              func (*Container) Exists

                                                              func (g *Container) Exists(hierarchy ...string) bool

                                                                Exists checks whether a path exists.

                                                                func (*Container) ExistsP

                                                                func (g *Container) ExistsP(path string) bool

                                                                  ExistsP checks whether a dot notation path exists.

                                                                  func (*Container) Index

                                                                  func (g *Container) Index(index int) *Container

                                                                    Index attempts to find and return an element within a JSON array by an index.

                                                                    func (*Container) JSONPointer

                                                                    func (g *Container) JSONPointer(path string) (*Container, error)

                                                                      JSONPointer parses a JSON pointer path (https://tools.ietf.org/html/rfc6901) and either returns a *gabs.Container containing the result or an error if the referenced item could not be found.

                                                                      func (*Container) Merge

                                                                      func (g *Container) Merge(source *Container) error

                                                                        Merge a source object into an existing destination object. When a collision is found within the merged structures (both a source and destination object contain the same non-object keys) the result will be an array containing both values, where values that are already arrays will be expanded into the resulting array.

                                                                        It is possible to merge structures will different collision behaviours with MergeFn.

                                                                        func (*Container) MergeFn

                                                                        func (g *Container) MergeFn(source *Container, collisionFn func(destination, source interface{}) interface{}) error

                                                                          MergeFn merges two objects using a provided function to resolve collisions.

                                                                          The collision function receives two interface{} arguments, destination (the original object) and source (the object being merged into the destination). Which ever value is returned becomes the new value in the destination object at the location of the collision.

                                                                          func (*Container) Object

                                                                          func (g *Container) Object(path ...string) (*Container, error)

                                                                            Object creates a new JSON object at a target path. Returns an error if the path contains a collision with a non object type.

                                                                            func (*Container) ObjectI

                                                                            func (g *Container) ObjectI(index int) (*Container, error)

                                                                              ObjectI creates a new JSON object at an array index. Returns an error if the object is not an array or the index is out of bounds.

                                                                              func (*Container) ObjectP

                                                                              func (g *Container) ObjectP(path string) (*Container, error)

                                                                                ObjectP creates a new JSON object at a target path using dot notation. Returns an error if the path contains a collision with a non object type.

                                                                                func (*Container) Path

                                                                                func (g *Container) Path(path string) *Container

                                                                                  Path searches the JSON structure following a path in dot notation.

                                                                                  func (*Container) S

                                                                                  func (g *Container) S(hierarchy ...string) *Container

                                                                                    S is a shorthand alias for Search.

                                                                                    func (*Container) Search

                                                                                    func (g *Container) Search(hierarchy ...string) *Container

                                                                                      Search attempts to find and return an object within the JSON structure by following a provided hierarchy of field names to locate the target. If the search encounters an array and has not reached the end target then it will iterate each object of the array for the target and return all of the results in a JSON array.

                                                                                      func (*Container) Set

                                                                                      func (g *Container) Set(value interface{}, path ...string) (*Container, error)

                                                                                        Set the value of a field at a JSON path, any parts of the path that do not exist will be constructed, and if a collision occurs with a non object type whilst iterating the path an error is returned.

                                                                                        func (*Container) SetIndex

                                                                                        func (g *Container) SetIndex(value interface{}, index int) (*Container, error)

                                                                                          SetIndex attempts to set a value of an array element based on an index.

                                                                                          func (*Container) SetJSONPointer

                                                                                          func (g *Container) SetJSONPointer(value interface{}, path string) error

                                                                                            SetJSONPointer parses a JSON pointer path (https://tools.ietf.org/html/rfc6901) and sets the leaf to a value. Returns an error if the pointer could not be resolved due to missing fields.

                                                                                            func (*Container) SetP

                                                                                            func (g *Container) SetP(value interface{}, path string) (*Container, error)

                                                                                              SetP sets the value of a field at a JSON path using dot notation, any parts of the path that do not exist will be constructed, and if a collision occurs with a non object type whilst iterating the path an error is returned.

                                                                                              func (*Container) String

                                                                                              func (g *Container) String() string

                                                                                                String marshals an element to a JSON formatted string.

                                                                                                func (*Container) StringIndent

                                                                                                func (g *Container) StringIndent(prefix string, indent string) string

                                                                                                  StringIndent marshals an element to a JSON string formatted with a prefix and indent string.

                                                                                                  type EncodeOpt

                                                                                                  type EncodeOpt func(e *json.Encoder)

                                                                                                    EncodeOpt is a functional option for the EncodeJSON method.

                                                                                                    func EncodeOptHTMLEscape

                                                                                                    func EncodeOptHTMLEscape(doEscape bool) EncodeOpt

                                                                                                      EncodeOptHTMLEscape sets the encoder to escape the JSON for html.

                                                                                                      func EncodeOptIndent

                                                                                                      func EncodeOptIndent(prefix string, indent string) EncodeOpt

                                                                                                        EncodeOptIndent sets the encoder to indent the JSON output.

                                                                                                        Source Files