Golang the use of JSON library Gjson

Source: Internet
Author: User
Tags install go intel core i7

The official JSON library only supports serialization and deserialization of the whole. Like libraries in other languages, the JSON library supports operations such as a single getvalue/setvalue.
Find the next Golang related to the open source JSON library, Gjson star number is good, support the query function is very rich. But no interface is written. I didn't find a lap.
Find the JSON library with write capability. Only the definition type serialization or map serialization can be thought of. The following is the text, translated from the Project Readme:

Begin

Before you start using Gjson, install go and then run go get :

$ go get -u github.com/tidwall/gjson

Get value

The Get query specifies the path through which . to differentiate. such as "Name.last" or "age". If a matching path is found, the result is returned.

package mainimport "github.com/tidwall/gjson"const json = `{"name":{"first":"Janet","last":"Prichard"},"age":47}`func main() {    value := gjson.Get(json, "name.last")    println(value.String())}

Output Result:

Prichard

At the same time, there are GetMany methods to get the value in bulk, and the GetBytes method gets the byte slice.

Path resolution

The path is a series . of separated key concatenation.
The path may contain a wildcard ' * ' and '? '.
The array value is accessed by subscript.
Use ' # ' to get the value of the row in the element or to access the subpath.
.and wildcard characters can be escaped by ' \ '.

{  "name": {"first": "Tom", "last": "Anderson"},  "age":37,  "children": ["Sara","Alex","Jack"],  "fav.movie": "Deer Hunter",  "friends": [    {"first": "Dale", "last": "Murphy", "age": 44},    {"first": "Roger", "last": "Craig", "age": 68},    {"first": "Jane", "last": "Murphy", "age": 47}  ]}
"name.last"          >> "Anderson""age"                >> 37"children"           >> ["Sara","Alex","Jack"]"children.#"         >> 3"children.1"         >> "Alex""child*.2"           >> "Jack""c?ildren.0"         >> "Sara""fav\.movie"         >> "Deer Hunter""friends.#.first"    >> ["Dale","Roger","Jane"]"friends.1.last"     >> "Craig"

You can also #[...] query the array for the first matching item, or through the ' #[...] # ' query for all matching items.
Query support,,,, == != < <= > >= comparison operators and '% ' fuzzy matches.

friends.#[last=="Murphy"].first    >> "Dale"friends.#[last=="Murphy"]#.first   >> ["Dale","Jane"]friends.#[age>45]#.last            >> ["Craig","Murphy"]friends.#[first%"D*"].last         >> "Murphy"

JSON rows

Also supports JSON Lines, using .. prefixes to treat multiple lines of document as Count groups.

Like what:

{"name": "Gilbert", "age": 61}{"name": "Alexa", "age": 34}{"name": "May", "age": 57}{"name": "Deloise", "age": 44}
..#                   >> 4..1                   >> {"name": "Alexa", "age": 34}..3                   >> {"name": "Deloise", "age": 44}..#.name              >> ["Gilbert","Alexa","May","Deloise"]..#[name="May"].age   >> 57

ForEachLinesmethod to iterate over the JSON.

gjson.ForEachLine(json, func(line gjson.Result) bool{    println(line.String())    return true})

Result Type

Gjson supports JSON types including,, string number , and bool null . Arrays and objects are blocked by the underlying type returned.

ResultOne of the following types is held:

bool, for JSON booleansfloat64, for JSON numbersstring, for JSON string literalsnil, for JSON null

Direct access to value:

result.Type    // can be String, Number, True, False, Null, or JSONresult.Str     // holds the stringresult.Num     // holds the float64 numberresult.Raw     // holds the raw jsonresult.Index   // index of raw value in original json, zero means index unknown

There are a variety of handy functions to get the results:

result.Exists() boolresult.Value() interface{}result.Int() int64result.Uint() uint64result.Float() float64result.String() stringresult.Bool() boolresult.Time() time.Timeresult.Array() []gjson.Resultresult.Map() map[string]gjson.Resultresult.Get(path string) Resultresult.ForEach(iterator func(key, value Result) bool)result.Less(token Result, caseSensitive bool) bool

result.Value()method returns interface{} one of the go basic types.

result.Array()method returns a set of values.
If the result is a value that does not exist, an empty array will be returned.
If the result is not a JSON array, an array containing only one value will be returned.

boolean >> boolnumber  >> float64string  >> stringnull    >> nilarray   >> []interface{}object  >> map[string]interface{}

64-bit integers

result.Int()And result.Uint() The return is a 64-bit large number.

result.Int() int64    // -9223372036854775808 to 9223372036854775807result.Uint() int64   // 0 to 18446744073709551615

Read nested arrays

If you want to get all the LastName from the following JSON:

{  "programmers": [    {      "firstName": "Janet",       "lastName": "McLaughlin",     }, {      "firstName": "Elliotte",       "lastName": "Hunter",     }, {      "firstName": "Jason",       "lastName": "Harold",     }  ]}

You can use the following path programmers.#.lastName :

result := gjson.Get(json, "programmers.#.lastName")for _, name := range result.Array() {    println(name.String())}

You can also get the objects in the array:

name := gjson.Get(json, `programmers.#[lastName="Hunter"].firstName`)println(name.String())  // prints "Elliotte"

Object or array iteration

ForEachmethod allows you to quickly iterate over an object or an array.
Key and value are passed to the object's iterator function.
Only value is passed to the array. An iterator return false will terminate the iteration.

Simple Parse and get

Parse(json)The method can simply parse the JSON and result.Get(path) query the result.

For example, the following scenarios will return the same result:

gjson.Parse(json).Get("name").Get("last")gjson.Get(json, "name").Get("last")gjson.Get(json, "name.last")

Checks if value exists

Sometimes you want to know if a value exists.

value := gjson.Get(json, "name.last")if !value.Exists() {    println("no last name")} else {    println(value.String())}// Or as one stepif gjson.Get(json, "name.last").Exists() {    println("has a last name")}

Validating JSON

Get*And Parse* method expected JSON format is normal, if not normal, will return unexpected results.

If the JSON source you read is unpredictable, then you can verify this beforehand by Gjson.

if !gjson.Valid(json) {    return errors.New("invalid json")}value := gjson.Get(json, "name.last")

Deserialize to map

Deserialization to map[string]interface{} :

m, ok := gjson.Parse(json).Value().(map[string]interface{})if !ok {    // not a map}## 处理Bytes如果你的JSON包含字节数组切片, 与其调用`Get(string(data), path)`, 不如调用[GetBytes](https://godoc.org/github.com/tidwall/gjson#GetBytes)方法更优.```govar json []byte = ...result := gjson.GetBytes(json, path)

If you are using the gjson.GetBytes(json, path) method and you want to avoid result.Raw switching from to []byte , you can use this mode:

var json []byte = ...result := gjson.GetBytes(json, path)var raw []byteif result.Index > 0 {    raw = json[result.Index:result.Index+len(result.Raw)]} else {    raw = []byte(result.Raw)}

This is the best mode and does not reallocate memory for sub-slices. This mode uses a result.Index field that points directly to the location in the original JSON where raw data is located.
If result.Raw it is converted []byte , it result.Index will be 0.

Get multiple values at once

GetManyMethod can be used to fetch multiple values at the same time.

results := gjson.GetMany(json, "name.first", "name.last", "age")

The return value is a []Result type that always returns the number of positive incoming paths.

Performance

Tested the Gjson and the Encoding/json,
Ffjson,
Easyjson,
Jsonparser,
and Json-iterator

BenchmarkGJSONGet-8                  3000000        372 ns/op          0 B/op         0 allocs/opBenchmarkGJSONUnmarshalMap-8          900000       4154 ns/op       1920 B/op        26 allocs/opBenchmarkJSONUnmarshalMap-8           600000       9019 ns/op       3048 B/op        69 allocs/opBenchmarkJSONDecoder-8                300000      14120 ns/op       4224 B/op       184 allocs/opBenchmarkFFJSONLexer-8               1500000       3111 ns/op        896 B/op         8 allocs/opBenchmarkEasyJSONLexer-8             3000000        887 ns/op        613 B/op         6 allocs/opBenchmarkJSONParserGet-8             3000000        499 ns/op         21 B/op         0 allocs/opBenchmarkJSONIterator-8              3000000        812 ns/op        544 B/op         9 allocs/op

JSON used:

{  "widget": {    "debug": "on",    "window": {      "title": "Sample Konfabulator Widget",      "name": "main_window",      "width": 500,      "height": 500    },    "image": {       "src": "Images/Sun.png",      "hOffset": 250,      "vOffset": 250,      "alignment": "center"    },    "text": {      "data": "Click Here",      "size": 36,      "style": "bold",      "vOffset": 100,      "alignment": "center",      "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"    }  }}    

Each operation is rotated in the following search path:

widget.window.namewidget.image.hOffsetwidget.text.onMouseUp

These benchmarks are run on the MacBook Pro "2.8 GHz Intel Core i7, which you can find using go 1.8. Here.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.