Git Product home page Git Product logo

go-jmespath's Introduction

go-jmespath - A JMESPath implementation in Go

GoDoc codecov Go Report Card License: Apache-2.0

go-jmespath is a GO implementation of JMESPath, which is a query language for JSON. It will take a JSON document and transform it into another JSON document through a JMESPath expression.

Using go-jmespath is really easy. There's a single function you use, jmespath.Search:

> import "github.com/jmespath-community/go-jmespath"
>
> var jsondata = []byte(`{"foo": {"bar": {"baz": [0, 1, 2, 3, 4]}}}`) // your data
> var data interface{}
> err := json.Unmarshal(jsondata, &data)
> result, err := jmespath.Search("foo.bar.baz[2]", data)
result = 2

In the example we gave the Search function input data of {"foo": {"bar": {"baz": [0, 1, 2, 3, 4]}}} as well as the JMESPath expression foo.bar.baz[2], and the Search function evaluated the expression against the input data to produce the result 2.

The JMESPath language can do a lot more than select an element from a list. Here are a few more examples:

> var jsondata = []byte(`{"foo": {"bar": {"baz": [0, 1, 2, 3, 4]}}}`) // your data
> var data interface{}
> err := json.Unmarshal(jsondata, &data)
> result, err := jmespath.Search("foo.bar", data)
result = { "baz": [ 0, 1, 2, 3, 4 ] }


> var jsondata  = []byte(`{"foo": [{"first": "a", "last": "b"},
                           {"first": "c", "last": "d"}]}`) // your data
> var data interface{}
> err := json.Unmarshal(jsondata, &data)
> result, err := jmespath.Search({"foo[*].first", data)
result [ 'a', 'c' ]


> var jsondata = []byte(`{"foo": [{"age": 20}, {"age": 25},
                           {"age": 30}, {"age": 35},
                           {"age": 40}]}`) // your data
> var data interface{}
> err := json.Unmarshal(jsondata, &data)
> result, err := jmespath.Search("foo[?age > `30`]")
result = [ { age: 35 }, { age: 40 } ]

You can also pre-compile your query. This is usefull if you are going to run multiple searches with it:

> var jsondata = []byte(`{"foo": "bar"}`)
> var data interface{}
> err := json.Unmarshal(jsondata, &data)
> precompiled, err := Compile("foo")
> if err != nil{
>   // ... handle the error
> }
> result, err := precompiled.Search(data)
result = "bar"

More Resources

The example above only show a small amount of what a JMESPath expression can do. If you want to take a tour of the language, the best place to go is the JMESPath Tutorial.

One of the best things about JMESPath is that it is implemented in many different programming languages including python, ruby, php, lua, etc. To see a complete list of libraries, check out the JMESPath libraries page.

And finally, the full JMESPath specification can be found on the JMESPath site.

go-jmespath's People

Contributors

jamesls avatar eddycharly avatar springcomp avatar dependabot[bot] avatar jasdel avatar ejholmes avatar ajorg-aws avatar brianbland avatar clinty avatar eparis avatar highlyunavailable avatar reedobrien avatar shawnps avatar willabides avatar shawnps-sigsci avatar xibz avatar

Stargazers

Tim avatar Shaolong Chen avatar Luis Davim avatar Sebastien Rosset avatar Ryan Parman avatar

Watchers

Jim Bugwadia avatar

go-jmespath's Issues

potential bug with `$`

This unit test should fail I think:

	{
		args: args{
			expression: `@."$".a`,
			data: map[string]interface{}{
				"a": 42.0,
			},
		},
		want: 42.0,
	}

We are clearly trying to access the $ field under the current node, but as it doesn't exist we fall back to root node.

cc @springcomp

main vs master

Hi ๐Ÿ‘‹
I see we have main and master branches, which one is the official one ?

Projected string slices are shortcut

See jmespath.test#32

Currently, string slices are implemented using the projection mechanism.
However, the second hand of the projection is not evaluated when slicing a string.

As a result, the following expression does not evaluate correctly:

  • 'foo'[::-1].length(@) -> "oof" โŒ

Instead, it should yield the following result:

  • 'foo'[::-1].length(@) -> 3 โœ…

Issue with filtering by comparison

The Go package does not seem to properly execute comparison queries. For example, if I have data:

{
  "resources": [
    {
      "description": "old",
      "updated_at": "2023-04-05"
    },
    {
      "description": "new",
      "updated_at": "2024-03-06",
    }
  ]
}

and execute query

resources[?updated_at > '2024-02-01']

the filtered result should only include the "new" resource. When I run this same example in the playground on the JMESPath site, I see the behavior I expect. When I run this in my Go code, I receive no results back from the search. Clearly, something is wrong in the Go code.

Also see the related issue against the original repo.

Compliant error reporting

While working on this project I noticed that compliance tests that check for errors do not in fact enforce the specific error type. They only report success if any error occurred.

This issue is a reminder to please, consider reporting compliant errors and enforcing checks for speciied error types, like invalid-type, syntax, etc.

Consider enabling CodeQL

I just learned about CodeQL and it seems quite interesting for detecting vulnerabilities.
Is there something you have had experience in the past?
Would it be worth it to enable CodeQL scanning on this repository?

fix scope related bug

This test should fail:

	{
		args: args{
			expression: `let({"b": @.a}, &a.b)`,
			data: map[string]interface{}{
				"a": 42.0,
			},
		},
		want: 42.0,
	}

Once &a has been looked up from the scope, we should not use the scope again to lookup .b.

@springcomp am I right thinking we have a bug here ?

enable CODECOV

A request has been sent to the org to enable CODECOV access.
The request must be accepted by an admin.

cc @springcomp

enable DCO

A request should have been sent to the org to instal DCO integration.
An org admin needs to allow it.

cc @springcomp

configure main branch protection

  • Require a pull request before merging
    • Require approvals
    • Dismiss stale pull request approvals when new commits are pushed
    • Require review from Code Owners
  • Require status checks to pass before merging
  • Require signed commits
  • Require linear history
  • Do not allow bypassing the above settings

configure repo settings

  • Require contributors to sign off on web-based commits
  • Disable wiki
  • Enable Discussions
  • Disable merge commits
  • Enable always suggest updating pull request branches
  • Enable allow auto-merge
  • Enable automatically delete head branches

potentially non deterministic code

This can be non deterministic

type byExprFloat struct {
intr Interpreter
node parsing.ASTNode
items []interface{}
hasError bool
}
func (a *byExprFloat) Len() int {
return len(a.items)
}
func (a *byExprFloat) Swap(i, j int) {
a.items[i], a.items[j] = a.items[j], a.items[i]
}
func (a *byExprFloat) Less(i, j int) bool {
first, err := a.intr.Execute(a.node, a.items[i])
if err != nil {
a.hasError = true
// Return a dummy value.
return true
}
ith, ok := first.(float64)
if !ok {
a.hasError = true
return true
}
second, err := a.intr.Execute(a.node, a.items[j])
if err != nil {
a.hasError = true
// Return a dummy value.
return true
}
jth, ok := second.(float64)
if !ok {
a.hasError = true
return true
}
return ith < jth
}

If items are random for example, invoking the interpreter every time Less is called will result in undefined behaviour.
It could eventually never terminate if comparison result constantly changes.

We should first calculate all values and sort those values after that.

cc @springcomp

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.