{"id":13413714,"url":"https://github.com/AsaiYusuke/jsonpath","last_synced_at":"2025-03-14T19:33:13.466Z","repository":{"id":42990971,"uuid":"316884027","full_name":"AsaiYusuke/jsonpath","owner":"AsaiYusuke","description":"A query library for retrieving part of JSON based on JSONPath syntax.","archived":false,"fork":false,"pushed_at":"2023-10-28T11:09:36.000Z","size":1122,"stargazers_count":25,"open_issues_count":1,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-07-31T20:52:48.349Z","etag":null,"topics":["golang","json","jsonpath","parsing","peg"],"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/AsaiYusuke.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":"2020-11-29T05:37:26.000Z","updated_at":"2024-06-01T22:18:59.000Z","dependencies_parsed_at":"2023-10-23T13:39:03.599Z","dependency_job_id":"b4d87284-d50e-4124-8237-9807b1373033","html_url":"https://github.com/AsaiYusuke/jsonpath","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AsaiYusuke%2Fjsonpath","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AsaiYusuke%2Fjsonpath/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AsaiYusuke%2Fjsonpath/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AsaiYusuke%2Fjsonpath/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AsaiYusuke","download_url":"https://codeload.github.com/AsaiYusuke/jsonpath/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243635836,"owners_count":20323005,"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","jsonpath","parsing","peg"],"created_at":"2024-07-30T20:01:47.201Z","updated_at":"2025-03-14T19:33:13.054Z","avatar_url":"https://github.com/AsaiYusuke.png","language":"Go","readme":"# AsaiYusuke/JSONPath\n\n[![Test](https://github.com/AsaiYusuke/jsonpath/actions/workflows/test.yml/badge.svg)](https://github.com/AsaiYusuke/jsonpath/actions/workflows/test.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/AsaiYusuke/jsonpath)](https://goreportcard.com/report/github.com/AsaiYusuke/jsonpath)\n[![Coverage Status](https://coveralls.io/repos/github/AsaiYusuke/jsonpath/badge.svg?branch=main)](https://coveralls.io/github/AsaiYusuke/jsonpath?branch=main)\n[![Go Reference](https://pkg.go.dev/badge/github.com/AsaiYusuke/jsonpath.svg)](https://pkg.go.dev/github.com/AsaiYusuke/jsonpath)\n[![Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go#query-language)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n![AsaiYusuke/JSONPath](assets/logo.svg)\n\nThis [Go](https://golang.org/) library is for retrieving a part of JSON according to the _JSONPath_ query syntax.\n\nThe core JSONPath syntax on which this library based:\n\n- [Stefan Gössner's JSONPath - XPath for JSON](https://goessner.net/articles/JsonPath/)\n- [Christoph Burgmer's json-path-comparison](https://github.com/cburgmer/json-path-comparison)\n- [JSONPath Internet Draft Development](https://github.com/ietf-wg-jsonpath/draft-ietf-jsonpath-jsonpath)\n\n#### Note:\n\nFor syntax compatibility among other libraries, please check [:memo: my comparison results](https://asaiyusuke.github.io/jsonpath/cburgmer-json-path-comparison/docs/index.html).\n\n## Table of Contents\n\n- [Getting started](#getting-started)\n- [Basic design](#basic-design)\n- [How to use](#how-to-use)\n  - [Retrieve one-time or repeated](#-retrieve-one-time-or-repeated)\n  - [Error handling](#-error-handling)\n  - [Function syntax](#-function-syntax)\n  - [Accessing JSON](#-accessing-json)\n- [Differences](#differences)\n- [Benchmarks](#benchmarks)\n- [Project progress](#project-progress)\n\n## Getting started\n\n### Install:\n\n```bash\ngo get github.com/AsaiYusuke/jsonpath\n```\n\n### Simple example:\n\n```go\npackage main\n\nimport (\n  \"encoding/json\"\n  \"fmt\"\n\n  \"github.com/AsaiYusuke/jsonpath\"\n)\n\nfunc main() {\n  jsonPath, srcJSON := `$.key`, `{\"key\":\"value\"}`\n  var src interface{}\n  json.Unmarshal([]byte(srcJSON), \u0026src)\n  output, _ := jsonpath.Retrieve(jsonPath, src)\n  outputJSON, _ := json.Marshal(output)\n  fmt.Println(string(outputJSON))\n  // Output:\n  // [\"value\"]\n}\n```\n\n## Basic design\n\n#### _Streamlined Development_\n\n- The JSONPath syntax analysis functionality has been separated using [PEG](https://github.com/pointlander/peg), resulting in a more simplified source code.\n- Robust unit testing has been implemented to prevent bugs and ensure consistent outcomes.\n\n#### _User-Friendly Interface_\n\n- The library is equipped with a comprehensive error specification, allowing users to effectively handle any errors that may arise.\n\n#### _Unwavering Compatibility_\n\n- The library has integrated a greater level of consensus behavior from [Christoph Burgmer's json-path-comparison](https://github.com/cburgmer/json-path-comparison), ensuring seamless compatibility.\n\n## How to use\n\n### \\* Retrieve one-time or repeated\n\nThe `Retrieve` function returns retrieved result using JSONPath and JSON object:\n\n```go\noutput, err := jsonpath.Retrieve(jsonPath, src)\n```\n\n[:memo: Example](https://pkg.go.dev/github.com/AsaiYusuke/jsonpath#example-Retrieve)\n\nThe `Parse` function returns a _parser-function_ that completed to check JSONPath syntax.\nBy using _parser-function_, it can repeat to retrieve with the same JSONPath :\n\n```go\njsonPath, err := jsonpath.Parse(jsonPath)\noutput1, err1 := jsonPath(src1)\noutput2, err2 := jsonPath(src2)\n:\n```\n\n[:memo: Example](https://pkg.go.dev/github.com/AsaiYusuke/jsonpath#example-Parse)\n\n### \\* Error handling\n\nIf there is a problem with the execution of _APIs_, an error type returned.\nThese error types define the corresponding symptom, as listed below:\n\n#### Syntax check errors from `Retrieve`, `Parse`\n\n| Error type              | Message format                                     | Symptom                                                                                                          | Ex                                                                                        |\n| ----------------------- | -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |\n| `ErrorInvalidSyntax`    | `invalid syntax (position=%d, reason=%s, near=%s)` | The invalid syntax found in the JSONPath.\u003cbr\u003eThe _reason_ including in this message will tell you more about it. | [:memo:](https://pkg.go.dev/github.com/AsaiYusuke/jsonpath#example-ErrorInvalidSyntax)    |\n| `ErrorInvalidArgument`  | `invalid argument (argument=%s, error=%s)`         | The argument specified in the JSONPath treated as the invalid error in Go syntax.                                | [:memo:](https://pkg.go.dev/github.com/AsaiYusuke/jsonpath#example-ErrorInvalidArgument)  |\n| `ErrorFunctionNotFound` | `function not found (function=%s)`                 | The function specified in the JSONPath is not found.                                                             | [:memo:](https://pkg.go.dev/github.com/AsaiYusuke/jsonpath#example-ErrorFunctionNotFound) |\n| `ErrorNotSupported`     | `not supported (feature=%s, path=%s)`              | The unsupported syntaxes specified in the JSONPath.                                                              | [:memo:](https://pkg.go.dev/github.com/AsaiYusuke/jsonpath#example-ErrorNotSupported)     |\n\n#### Runtime errors from `Retrieve`, _`parser-functions`_\n\n| Error type            | Message format                                    | Symptom                                                                             | Ex                                                                                      |\n| --------------------- | ------------------------------------------------- | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |\n| `ErrorMemberNotExist` | `member did not exist (path=%s)`                  | The object/array member specified in the JSONPath did not exist in the JSON object. | [:memo:](https://pkg.go.dev/github.com/AsaiYusuke/jsonpath#example-ErrorMemberNotExist) |\n| `ErrorTypeUnmatched`  | `type unmatched (expected=%s, found=%s, path=%s)` | The node type specified in the JSONPath did not exist in the JSON object.           | [:memo:](https://pkg.go.dev/github.com/AsaiYusuke/jsonpath#example-ErrorTypeUnmatched)  |\n| `ErrorFunctionFailed` | `function failed (function=%s, error=%s)`         | The function specified in the JSONPath failed.                                      | [:memo:](https://pkg.go.dev/github.com/AsaiYusuke/jsonpath#example-ErrorFunctionFailed) |\n\nThe type checking is convenient to recognize which error happened.\n\n```go\n  :\n  _,err := jsonpath.Retrieve(jsonPath, srcJSON)\n  if err != nil {\n    switch err.(type) {\n    case jsonpath.ErrorMemberNotExist:\n      fmt.printf(`retry with other srcJSON: %v`, err)\n      continue\n    case jsonpath.ErrorInvalidArgumentFormat:\n      return nil, fmt.errorf(`specified invalid argument: %v`, err)\n    }\n    :\n  }\n```\n\n### \\* Function syntax\n\nFunction enables to format results by using user defined functions.\nThe function syntax comes after the JSONPath.\n\nThere are two ways to use function:\n\n#### Filter function\n\nThe filter function applies a user function to each values in the result to get converted.\n\n[:memo: Example](https://pkg.go.dev/github.com/AsaiYusuke/jsonpath#example-Config.SetFilterFunction)\n\n#### Aggregate function\n\nThe aggregate function converts all values in the result into a single value.\n\n[:memo: Example](https://pkg.go.dev/github.com/AsaiYusuke/jsonpath#example-Config.SetAggregateFunction)\n\n### \\* Accessing JSON\n\nYou can get the accessors ( _Getters / Setters_ ) of the input JSON instead of the retrieved values.\nThese accessors can use to update for the input JSON.\n\nThis feature can get enabled by giving `Config.SetAccessorMode()`.\n\n[:memo: Example](https://pkg.go.dev/github.com/AsaiYusuke/jsonpath#example-Config.SetAccessorMode)\n\n#### Note:\n\nIt is not possible to use _Setter_ for some results, such as for JSONPath including function syntax.\n\nAlso, operations using accessors follow the map/slice manner of Go language.\nIf you use accessors after changing the structure of JSON, you need to pay attention to the behavior.\nIf you don't want to worry about it, get the accessor again every time you change the structure.\n\n## Differences\n\nSome behaviors that differ from the consensus exists in this library.\nFor the entire comparisons, please check [:memo: this result](https://asaiyusuke.github.io/jsonpath/cburgmer-json-path-comparison/docs/index.html).\n\nThese behaviors will change in the future if appropriate ones found.\n\n### Character types\n\nThe following character types can be available for identifiers in dot-child notation.\n\n| Character type                                                                                                                                                                | Available | Escape required |\n| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | --------------- |\n| \\* Numbers and alphabets (`0-9` `A-Z` `a-z`)\u003cbr\u003e \\* Hyphen and underscore (`-` `_`)\u003cbr\u003e \\* Non-ASCII Unicode characters (`0x80 - 0x10FFFF`)                                     | Yes       | No              |\n| \\* Other printable symbols (`Space` `!` `\"` `#` `$` `%` `\u0026` `'` `(` `)` `*` `+` `,` `.` `/` `:` `;` `\u003c` `=` `\u003e` `?` `@` `[` `\\` `]` `^` `` ` `` `{` \u003ccode\u003e\u0026#124;\u003c/code\u003e `}` `~`) | Yes       | Yes             |\n| \\* ~~Control code characters~~ (`0x00 - 0x1F`, `0x7F`)                                                                                                                        | No        | -               |\n\nThe printable symbols except hyphen and underscore can use by escaping them.\n\n```text\nJSONPath : $.abc\\.def\nsrcJSON  : {\"abc.def\":1}\nOutput   : [1]\n```\n\n### Wildcard in qualifier\n\nThe wildcards in qualifier can specify as a union of subscripts.\n\n```text\nJSONPath : $[0,1:3,*]\nsrcJSON  : [0,1,2,3,4,5]\nOutput   : [0,1,2,0,1,2,3,4,5]\n```\n\n### Regular expression\n\nThe regular expression syntax works as a regular expression in Go lang.\nIn particular, you can use \"(?i)\" to specify the regular expression as the ignore case option.\n\n```text\nJSONPath : $[?(@=~/(?i)CASE/)]\nsrcJSON  : [\"Case\",\"Hello\"]\nOutput   : [\"Case\"]\n```\n\n### JSONPaths in the filter-qualifier\n\nJSONPaths that return a value group cannot use with `comparator` or `regular expression`. However, `existence check` can use these syntaxes.\n\n| JSONPaths that return a value group | example       |\n| ----------------------------------- | ------------- |\n| Recursive descent                   | `@..a`        |\n| Multiple identifier                 | `@['a','b']`  |\n| Wildcard identifier                 | `@.*`         |\n| Slice qualifier                     | `@[0:1]`      |\n| Wildcard qualifier                  | `@[*]`        |\n| Union in the qualifier              | `@[0,1]`      |\n| Filter qualifier                    | `@.a[?(@.b)]` |\n\n- comparator example (error)\n\n```text\nJSONPath : $[?(@..x == \"hello world\")]\nsrcJSON  : [{\"a\":1},{\"b\":{\"x\":\"hello world\"}}]\nError    : ErrorInvalidSyntax\n```\n\n- regular expression example (error)\n\n```text\nJSONPath : $[?(@..x=~/hello/)]\nsrcJSON  : [{\"a\":1},{\"b\":{\"x\":\"hello world\"}}]\nError    : ErrorInvalidSyntax\n```\n\n- existence check example\n\n```text\nJSONPath : $[?(@..x)]\nsrcJSON  : [{\"a\":1},{\"b\":{\"x\":\"hello world\"}}]\nOutput   : [{\"b\":{\"x\":\"hello world\"}}]\n```\n\nJSONPath filter that begins with Root is a whole-match operation when any one is detected.\n\n```text\nJSONPath : $[?($..x)]\nsrcJSON  : [{\"a\":1},{\"b\":{\"x\":\"hello world\"}}]\nOutput   : [{\"a\":1},{\"b\":{\"x\":\"hello world\"}}]\n```\n\n## Benchmarks\n\nThe benchmarks for various JSONPath libraries in Go language can be compared in the following repository.\n\n- [JSONPath Benchmark](https://github.com/AsaiYusuke/jsonpath-benchmark)\n\n## Project progress\n\n- Syntax\n  - Identifier\n    - [x] identifier in dot notations\n    - [x] identifier in bracket notations\n    - [x] wildcard\n    - [x] multiple-identifier in bracket\n    - [x] recursive retrieve\n  - Qualifier\n    - [x] index\n    - [x] slice\n    - [x] wildcard\n    - Filter\n      - [x] logical operation\n      - [x] comparator\n      - [x] JSONPath retrieve in filter\n    - [ ] script\n  - Function\n    - [x] filter\n    - [x] aggregate\n  - [x] Refer to the consensus behaviors\n- Architecture\n  - [x] PEG syntax analyzing\n  - [x] Error handling\n  - [x] Function\n  - [x] Accessing JSON\n- Go language manner\n  - [x] retrieve with the object in interface unmarshal\n  - [x] retrieve with the json.Number type\n- Source code\n  - [x] Release version\n  - Unit tests\n    - [x] syntax tests\n    - [x] benchmark\n    - [x] coverage \u003e80%\n  - [x] Examples\n  - [x] CI automation\n  - Documentation\n    - [x] README\n    - [ ] API doc\n  - [x] comparison result (local)\n- Development status\n  - [x] determine requirements / functional design\n  - [x] design-based coding\n  - [ ] testing\n  - [ ] documentation\n- Future ToDo\n  - [ ] Refer to the something standard\n  - Go language affinity\n    - [ ] retrieve with the object in struct unmarshal\n    - [ ] retrieve with the struct tags\n    - [ ] retrieve with the user defined objects\n","funding_links":[],"categories":["Query Language","查询语言","Relational Databases","Go"],"sub_categories":["HTTP Clients","HTTP客户端"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAsaiYusuke%2Fjsonpath","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FAsaiYusuke%2Fjsonpath","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAsaiYusuke%2Fjsonpath/lists"}