PaesslerAG / jsonpath

BSD 3-Clause "New" or "Revised" License
172 stars 37 forks source link

Examples from https://goessner.net/articles/JsonPath/ don't work #8

Closed kabukky closed 5 years ago

kabukky commented 5 years ago

Hi, sorry for opening another issue so soon after the first one. I took a few examples off https://goessner.net/articles/JsonPath/index.html#e3 but can't get them to work.

Example code:

    v := interface{}(nil)

    json.Unmarshal([]byte(`{ "store": {
        "book": [ 
          { "category": "reference",
            "author": "Nigel Rees",
            "title": "Sayings of the Century",
            "price": 8.95
          },
          { "category": "fiction",
            "author": "Evelyn Waugh",
            "title": "Sword of Honour",
            "price": 12.99
          },
          { "category": "fiction",
            "author": "Herman Melville",
            "title": "Moby Dick",
            "isbn": "0-553-21311-3",
            "price": 8.99
          },
          { "category": "fiction",
            "author": "J. R. R. Tolkien",
            "title": "The Lord of the Rings",
            "isbn": "0-395-19395-8",
            "price": 22.99
          }
        ],
        "bicycle": {
          "color": "red",
          "price": 19.95
        }
      }
    }`), &v)

    result, err := jsonpath.Get("$..book[?(@.isbn)]", v)
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }

    fmt.Println(result)

Will print an empty result.

Other results using the example expressions:

1 suggests that expressions containing [?(@.foo)] should work, but I can't reproduce that.

Does your syntax differ from https://goessner.net/articles/JsonPath/ ?

generikvault commented 5 years ago

No problem.

Jsonpath itself doesn't contain a script language. The examples from goessner use java script (@.length-1)] and (@.price<10).

This lib does not include javascribt but it is build in a way that it can be extended. So you can include a scripting language. Take a look at the gval example. It includes the expression language gval https://github.com/PaesslerAG/gval and is able to evaluate minus and smaller than operators.

generikvault commented 5 years ago

I should probably include this to the package description.

kabukky commented 5 years ago

Thanks! That makes sense. I'm creating the language using gval.Full(...) now, which works great:

expression := "$..book[?(@.price<10)]"
jsonPathLanguage = gval.Full(jsonpath.Language(), gvalstrings.SingleQuoted())
...
path, err := jsonPathLanguage.NewEvaluable(expression)
...
result, err := path(context.Background(), v)

I realize this questions is probably better suited for gval, but: Is there a way with gval to simply test for the existence of a field? The expression $..book[?(@.isbn)] will return books where the isbn field is a boolean with value true.

generikvault commented 5 years ago

I haven't implemented a === or a nil / null constant. If you're interessted feel free to implement it 😃 A json object is represented by a map[string]interface{} so $..book[?("isbn" in @)]. In this case $..book[?(@.isbn != "")] should also do the job.

kabukky commented 5 years ago

I'll try that! Thanks for putting up with me :)