{"id":13393919,"url":"https://github.com/tidwall/gjson","last_synced_at":"2025-05-12T16:32:49.285Z","repository":{"id":37405832,"uuid":"65434192","full_name":"tidwall/gjson","owner":"tidwall","description":"Get JSON values quickly - JSON parser for Go","archived":false,"fork":false,"pushed_at":"2024-10-10T10:43:48.000Z","size":517,"stargazers_count":14905,"open_issues_count":87,"forks_count":867,"subscribers_count":166,"default_branch":"master","last_synced_at":"2025-05-05T14:48:38.477Z","etag":null,"topics":["golang","json","json-parser"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tidwall.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-08-11T03:08:47.000Z","updated_at":"2025-05-04T10:36:13.000Z","dependencies_parsed_at":"2022-07-08T19:01:50.103Z","dependency_job_id":"e7e77c11-c8c0-4f7d-b065-3f3150838629","html_url":"https://github.com/tidwall/gjson","commit_stats":{"total_commits":284,"total_committers":31,"mean_commits":9.161290322580646,"dds":"0.12323943661971826","last_synced_commit":"4d230282c0e3bf42fa509147d27d7e8dcc3d3bad"},"previous_names":[],"tags_count":67,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tidwall%2Fgjson","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tidwall%2Fgjson/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tidwall%2Fgjson/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tidwall%2Fgjson/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tidwall","download_url":"https://codeload.github.com/tidwall/gjson/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253776964,"owners_count":21962603,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["golang","json","json-parser"],"created_at":"2024-07-30T17:01:02.582Z","updated_at":"2025-05-12T16:32:49.259Z","avatar_url":"https://github.com/tidwall.png","language":"Go","readme":"\u003cp align=\"center\"\u003e\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"/.github/images/logo-dark.png\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"/.github/images/logo-light.png\"\u003e\n  \u003cimg src=\"/.github/images/logo-light.png\" width=\"240\" alt=\"GJSON\" \u003e\n\u003c/picture\u003e\n\u003cbr\u003e\n\u003ca href=\"https://godoc.org/github.com/tidwall/gjson\"\u003e\u003cimg src=\"https://img.shields.io/badge/api-reference-blue.svg?style=flat-square\" alt=\"GoDoc\"\u003e\u003c/a\u003e\n\u003ca href=\"https://tidwall.com/gjson-play\"\u003e\u003cimg src=\"https://img.shields.io/badge/%F0%9F%8F%90-playground-9900cc.svg?style=flat-square\" alt=\"GJSON Playground\"\u003e\u003c/a\u003e\n\u003ca href=\"SYNTAX.md\"\u003e\u003cimg src=\"https://img.shields.io/badge/{}-syntax-33aa33.svg?style=flat-square\" alt=\"GJSON Syntax\"\u003e\u003c/a\u003e\n\t\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003eget json values quickly\u003c/a\u003e\u003c/p\u003e\n\nGJSON is a Go package that provides a [fast](#performance) and [simple](#get-a-value) way to get values from a json document.\nIt has features such as [one line retrieval](#get-a-value), [dot notation paths](#path-syntax), [iteration](#iterate-through-an-object-or-array), and [parsing json lines](#json-lines).\n\nAlso check out [SJSON](https://github.com/tidwall/sjson) for modifying json, and the [JJ](https://github.com/tidwall/jj) command line tool.\n\nThis README is a quick overview of how to use GJSON, for more information check out [GJSON Syntax](SYNTAX.md).\n\nGJSON is also available for [Python](https://github.com/volans-/gjson-py) and [Rust](https://github.com/tidwall/gjson.rs)\n\nGetting Started\n===============\n\n## Installing\n\nTo start using GJSON, install Go and run `go get`:\n\n```sh\n$ go get -u github.com/tidwall/gjson\n```\n\nThis will retrieve the library.\n\n## Get a value\nGet searches json for the specified path. A path is in dot syntax, such as \"name.last\" or \"age\". When the value is found it's returned immediately. \n\n```go\npackage main\n\nimport \"github.com/tidwall/gjson\"\n\nconst json = `{\"name\":{\"first\":\"Janet\",\"last\":\"Prichard\"},\"age\":47}`\n\nfunc main() {\n\tvalue := gjson.Get(json, \"name.last\")\n\tprintln(value.String())\n}\n```\n\nThis will print:\n\n```\nPrichard\n```\n*There's also [GetBytes](#working-with-bytes) for working with JSON byte slices.*\n\n## Path Syntax\n\nBelow is a quick overview of the path syntax, for more complete information please\ncheck out [GJSON Syntax](SYNTAX.md).\n\nA path is a series of keys separated by a dot.\nA key may contain special wildcard characters '\\*' and '?'.\nTo access an array value use the index as the key.\nTo get the number of elements in an array or to access a child path, use the '#' character.\nThe dot and wildcard characters can be escaped with '\\\\'.\n\n```json\n{\n  \"name\": {\"first\": \"Tom\", \"last\": \"Anderson\"},\n  \"age\":37,\n  \"children\": [\"Sara\",\"Alex\",\"Jack\"],\n  \"fav.movie\": \"Deer Hunter\",\n  \"friends\": [\n    {\"first\": \"Dale\", \"last\": \"Murphy\", \"age\": 44, \"nets\": [\"ig\", \"fb\", \"tw\"]},\n    {\"first\": \"Roger\", \"last\": \"Craig\", \"age\": 68, \"nets\": [\"fb\", \"tw\"]},\n    {\"first\": \"Jane\", \"last\": \"Murphy\", \"age\": 47, \"nets\": [\"ig\", \"tw\"]}\n  ]\n}\n```\n```\n\"name.last\"          \u003e\u003e \"Anderson\"\n\"age\"                \u003e\u003e 37\n\"children\"           \u003e\u003e [\"Sara\",\"Alex\",\"Jack\"]\n\"children.#\"         \u003e\u003e 3\n\"children.1\"         \u003e\u003e \"Alex\"\n\"child*.2\"           \u003e\u003e \"Jack\"\n\"c?ildren.0\"         \u003e\u003e \"Sara\"\n\"fav\\.movie\"         \u003e\u003e \"Deer Hunter\"\n\"friends.#.first\"    \u003e\u003e [\"Dale\",\"Roger\",\"Jane\"]\n\"friends.1.last\"     \u003e\u003e \"Craig\"\n```\n\nYou can also query an array for the first match by using `#(...)`, or find all \nmatches with `#(...)#`. Queries support the `==`, `!=`, `\u003c`, `\u003c=`, `\u003e`, `\u003e=` \ncomparison operators and the simple pattern matching `%` (like) and `!%` \n(not like) operators.\n\n```\nfriends.#(last==\"Murphy\").first    \u003e\u003e \"Dale\"\nfriends.#(last==\"Murphy\")#.first   \u003e\u003e [\"Dale\",\"Jane\"]\nfriends.#(age\u003e45)#.last            \u003e\u003e [\"Craig\",\"Murphy\"]\nfriends.#(first%\"D*\").last         \u003e\u003e \"Murphy\"\nfriends.#(first!%\"D*\").last        \u003e\u003e \"Craig\"\nfriends.#(nets.#(==\"fb\"))#.first   \u003e\u003e [\"Dale\",\"Roger\"]\n```\n\n*Please note that prior to v1.3.0, queries used the `#[...]` brackets. This was\nchanged in v1.3.0 as to avoid confusion with the new\n[multipath](SYNTAX.md#multipaths) syntax. For backwards compatibility, \n`#[...]` will continue to work until the next major release.*\n\n## Result Type\n\nGJSON supports the json types `string`, `number`, `bool`, and `null`. \nArrays and Objects are returned as their raw json types. \n\nThe `Result` type holds one of these:\n\n```\nbool, for JSON booleans\nfloat64, for JSON numbers\nstring, for JSON string literals\nnil, for JSON null\n```\n\nTo directly access the value:\n\n```go\nresult.Type           // can be String, Number, True, False, Null, or JSON\nresult.Str            // holds the string\nresult.Num            // holds the float64 number\nresult.Raw            // holds the raw json\nresult.Index          // index of raw value in original json, zero means index unknown\nresult.Indexes        // indexes of all the elements that match on a path containing the '#' query character.\n```\n\nThere are a variety of handy functions that work on a result:\n\n```go\nresult.Exists() bool\nresult.Value() interface{}\nresult.Int() int64\nresult.Uint() uint64\nresult.Float() float64\nresult.String() string\nresult.Bool() bool\nresult.Time() time.Time\nresult.Array() []gjson.Result\nresult.Map() map[string]gjson.Result\nresult.Get(path string) Result\nresult.ForEach(iterator func(key, value Result) bool)\nresult.Less(token Result, caseSensitive bool) bool\n```\n\nThe `result.Value()` function returns an `interface{}` which requires type assertion and is one of the following Go types:\n\n```go\nboolean \u003e\u003e bool\nnumber  \u003e\u003e float64\nstring  \u003e\u003e string\nnull    \u003e\u003e nil\narray   \u003e\u003e []interface{}\nobject  \u003e\u003e map[string]interface{}\n```\n\nThe `result.Array()` function returns back an array of values.\nIf the result represents a non-existent value, then an empty array will be returned.\nIf the result is not a JSON array, the return value will be an array containing one result.\n\n### 64-bit integers\n\nThe `result.Int()` and `result.Uint()` calls are capable of reading all 64 bits, allowing for large JSON integers.\n\n```go\nresult.Int() int64    // -9223372036854775808 to 9223372036854775807\nresult.Uint() uint64   // 0 to 18446744073709551615\n```\n\n## Modifiers and path chaining \n\nNew in version 1.2 is support for modifier functions and path chaining.\n\nA modifier is a path component that performs custom processing on the \njson.\n\nMultiple paths can be \"chained\" together using the pipe character. \nThis is useful for getting results from a modified query.\n\nFor example, using the built-in `@reverse` modifier on the above json document,\nwe'll get `children` array and reverse the order:\n\n```\n\"children|@reverse\"           \u003e\u003e [\"Jack\",\"Alex\",\"Sara\"]\n\"children|@reverse|0\"         \u003e\u003e \"Jack\"\n```\n\nThere are currently the following built-in modifiers:\n\n- `@reverse`: Reverse an array or the members of an object.\n- `@ugly`: Remove all whitespace from a json document.\n- `@pretty`: Make the json document more human readable.\n- `@this`: Returns the current element. It can be used to retrieve the root element.\n- `@valid`: Ensure the json document is valid.\n- `@flatten`: Flattens an array.\n- `@join`: Joins multiple objects into a single object.\n- `@keys`: Returns an array of keys for an object.\n- `@values`: Returns an array of values for an object.\n- `@tostr`: Converts json to a string. Wraps a json string.\n- `@fromstr`: Converts a string from json. Unwraps a json string.\n- `@group`: Groups arrays of objects. See [e4fc67c](https://github.com/tidwall/gjson/commit/e4fc67c92aeebf2089fabc7872f010e340d105db).\n- `@dig`: Search for a value without providing its entire path. See [e8e87f2](https://github.com/tidwall/gjson/commit/e8e87f2a00dc41f3aba5631094e21f59a8cf8cbf).\n\n### Modifier arguments\n\nA modifier may accept an optional argument. The argument can be a valid JSON \ndocument or just characters.\n\nFor example, the `@pretty` modifier takes a json object as its argument. \n\n```\n@pretty:{\"sortKeys\":true} \n```\n\nWhich makes the json pretty and orders all of its keys.\n\n```json\n{\n  \"age\":37,\n  \"children\": [\"Sara\",\"Alex\",\"Jack\"],\n  \"fav.movie\": \"Deer Hunter\",\n  \"friends\": [\n    {\"age\": 44, \"first\": \"Dale\", \"last\": \"Murphy\"},\n    {\"age\": 68, \"first\": \"Roger\", \"last\": \"Craig\"},\n    {\"age\": 47, \"first\": \"Jane\", \"last\": \"Murphy\"}\n  ],\n  \"name\": {\"first\": \"Tom\", \"last\": \"Anderson\"}\n}\n```\n\n*The full list of `@pretty` options are `sortKeys`, `indent`, `prefix`, and `width`. \nPlease see [Pretty Options](https://github.com/tidwall/pretty#customized-output) for more information.*\n\n### Custom modifiers\n\nYou can also add custom modifiers.\n\nFor example, here we create a modifier that makes the entire json document upper\nor lower case.\n\n```go\ngjson.AddModifier(\"case\", func(json, arg string) string {\n  if arg == \"upper\" {\n    return strings.ToUpper(json)\n  }\n  if arg == \"lower\" {\n    return strings.ToLower(json)\n  }\n  return json\n})\n```\n\n```\n\"children|@case:upper\"           \u003e\u003e [\"SARA\",\"ALEX\",\"JACK\"]\n\"children|@case:lower|@reverse\"  \u003e\u003e [\"jack\",\"alex\",\"sara\"]\n```\n\n## JSON Lines\n\nThere's support for [JSON Lines](http://jsonlines.org/) using the `..` prefix, which treats a multilined document as an array. \n\nFor example:\n\n```\n{\"name\": \"Gilbert\", \"age\": 61}\n{\"name\": \"Alexa\", \"age\": 34}\n{\"name\": \"May\", \"age\": 57}\n{\"name\": \"Deloise\", \"age\": 44}\n```\n\n```\n..#                   \u003e\u003e 4\n..1                   \u003e\u003e {\"name\": \"Alexa\", \"age\": 34}\n..3                   \u003e\u003e {\"name\": \"Deloise\", \"age\": 44}\n..#.name              \u003e\u003e [\"Gilbert\",\"Alexa\",\"May\",\"Deloise\"]\n..#(name=\"May\").age   \u003e\u003e 57\n```\n\nThe `ForEachLines` function will iterate through JSON lines.\n\n```go\ngjson.ForEachLine(json, func(line gjson.Result) bool{\n    println(line.String())\n    return true\n})\n```\n\n## Get nested array values\n\nSuppose you want all the last names from the following json:\n\n```json\n{\n  \"programmers\": [\n    {\n      \"firstName\": \"Janet\", \n      \"lastName\": \"McLaughlin\", \n    }, {\n      \"firstName\": \"Elliotte\", \n      \"lastName\": \"Hunter\", \n    }, {\n      \"firstName\": \"Jason\", \n      \"lastName\": \"Harold\", \n    }\n  ]\n}\n```\n\nYou would use the path \"programmers.#.lastName\" like such:\n\n```go\nresult := gjson.Get(json, \"programmers.#.lastName\")\nfor _, name := range result.Array() {\n\tprintln(name.String())\n}\n```\n\nYou can also query an object inside an array:\n\n```go\nname := gjson.Get(json, `programmers.#(lastName=\"Hunter\").firstName`)\nprintln(name.String())  // prints \"Elliotte\"\n```\n\n## Iterate through an object or array\n\nThe `ForEach` function allows for quickly iterating through an object or array. \nThe key and value are passed to the iterator function for objects.\nOnly the value is passed for arrays.\nReturning `false` from an iterator will stop iteration.\n\n```go\nresult := gjson.Get(json, \"programmers\")\nresult.ForEach(func(key, value gjson.Result) bool {\n\tprintln(value.String()) \n\treturn true // keep iterating\n})\n```\n\n## Simple Parse and Get\n\nThere's a `Parse(json)` function that will do a simple parse, and `result.Get(path)` that will search a result.\n\nFor example, all of these will return the same result:\n\n```go\ngjson.Parse(json).Get(\"name\").Get(\"last\")\ngjson.Get(json, \"name\").Get(\"last\")\ngjson.Get(json, \"name.last\")\n```\n\n## Check for the existence of a value\n\nSometimes you just want to know if a value exists. \n\n```go\nvalue := gjson.Get(json, \"name.last\")\nif !value.Exists() {\n\tprintln(\"no last name\")\n} else {\n\tprintln(value.String())\n}\n\n// Or as one step\nif gjson.Get(json, \"name.last\").Exists() {\n\tprintln(\"has a last name\")\n}\n```\n\n## Validate JSON\n\nThe `Get*` and `Parse*` functions expects that the json is well-formed. Bad json will not panic, but it may return back unexpected results.\n\nIf you are consuming JSON from an unpredictable source then you may want to validate prior to using GJSON.\n\n```go\nif !gjson.Valid(json) {\n\treturn errors.New(\"invalid json\")\n}\nvalue := gjson.Get(json, \"name.last\")\n```\n\n## Unmarshal to a map\n\nTo unmarshal to a `map[string]interface{}`:\n\n```go\nm, ok := gjson.Parse(json).Value().(map[string]interface{})\nif !ok {\n\t// not a map\n}\n```\n\n## Working with Bytes\n\nIf your JSON is contained in a `[]byte` slice, there's the [GetBytes](https://godoc.org/github.com/tidwall/gjson#GetBytes) function. This is preferred over `Get(string(data), path)`.\n\n```go\nvar json []byte = ...\nresult := gjson.GetBytes(json, path)\n```\n\nIf you are using the `gjson.GetBytes(json, path)` function and you want to avoid converting `result.Raw` to a `[]byte`, then you can use this pattern:\n\n```go\nvar json []byte = ...\nresult := gjson.GetBytes(json, path)\nvar raw []byte\nif result.Index \u003e 0 {\n    raw = json[result.Index:result.Index+len(result.Raw)]\n} else {\n    raw = []byte(result.Raw)\n}\n```\n\nThis is a best-effort no allocation sub slice of the original json. This method utilizes the `result.Index` field, which is the position of the raw data in the original json. It's possible that the value of `result.Index` equals zero, in which case the `result.Raw` is converted to a `[]byte`.\n\n## Performance\n\nBenchmarks of GJSON alongside [encoding/json](https://golang.org/pkg/encoding/json/), \n[ffjson](https://github.com/pquerna/ffjson), \n[EasyJSON](https://github.com/mailru/easyjson),\n[jsonparser](https://github.com/buger/jsonparser),\nand [json-iterator](https://github.com/json-iterator/go)\n\n```\nBenchmarkGJSONGet-10             17893731    202.1 ns/op      0 B/op     0 allocs/op\nBenchmarkGJSONUnmarshalMap-10     1663548   2157 ns/op     1920 B/op    26 allocs/op\nBenchmarkJSONUnmarshalMap-10       832236   4279 ns/op     2920 B/op    68 allocs/op\nBenchmarkJSONUnmarshalStruct-10   1076475   3219 ns/op      920 B/op    12 allocs/op\nBenchmarkJSONDecoder-10            585729   6126 ns/op     3845 B/op   160 allocs/op\nBenchmarkFFJSONLexer-10           2508573   1391 ns/op      880 B/op     8 allocs/op\nBenchmarkEasyJSONLexer-10         3000000    537.9 ns/op    501 B/op     5 allocs/op\nBenchmarkJSONParserGet-10        13707510    263.9 ns/op     21 B/op     0 allocs/op\nBenchmarkJSONIterator-10          3000000    561.2 ns/op    693 B/op    14 allocs/op\n```\n\nJSON document used:\n\n```json\n{\n  \"widget\": {\n    \"debug\": \"on\",\n    \"window\": {\n      \"title\": \"Sample Konfabulator Widget\",\n      \"name\": \"main_window\",\n      \"width\": 500,\n      \"height\": 500\n    },\n    \"image\": { \n      \"src\": \"Images/Sun.png\",\n      \"hOffset\": 250,\n      \"vOffset\": 250,\n      \"alignment\": \"center\"\n    },\n    \"text\": {\n      \"data\": \"Click Here\",\n      \"size\": 36,\n      \"style\": \"bold\",\n      \"vOffset\": 100,\n      \"alignment\": \"center\",\n      \"onMouseUp\": \"sun1.opacity = (sun1.opacity / 100) * 90;\"\n    }\n  }\n}    \n```\n\nEach operation was rotated through one of the following search paths:\n\n```\nwidget.window.name\nwidget.image.hOffset\nwidget.text.onMouseUp\n```\n\n**\n\n*These benchmarks were run on a MacBook Pro M1 Max using Go 1.22 and can be found [here](https://github.com/tidwall/gjson-benchmarks).*\n","funding_links":[],"categories":["Popular","Go","开源类库","Misc","Relational Databases","JSON","工具库","Programming","JSON parsers \u0026 validators","Open source library","Utilities","實用工具","语言资源库","实用工具","Encoders","JSON 处理"],"sub_categories":["JSON","检索及分析资料库","交流","Golang","\u003cspan id=\"高级控制台用户界面-advanced-console-uis\"\u003e高级控制台用户界面 Advanced Console UIs\u003c/span\u003e","Search and Analytic Databases","SQL 查询语句构建库","Advanced Console UIs","高級控制台界面","go","Instrumentation and control with sensors and actuators","高级控制台界面","HTTP Clients"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftidwall%2Fgjson","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftidwall%2Fgjson","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftidwall%2Fgjson/lists"}