PaesslerAG / jsonpath

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

Allow json path to work in objects which are struct based interfaces #27

Open tarunlalwani opened 3 years ago

tarunlalwani commented 3 years ago

This fixes the problem where jsonpath.Get doesn't work if the root object is a struct instead of blank interface.

I wrote the below test that shows the issues and also the patch working

package main

import (
    "fmt"
    "github.com/PaesslerAG/jsonpath"
    jsoniter "github.com/json-iterator/go"
    jsonpathpatch "github.com/tarunlalwani/jsonpath"
)

var json = jsoniter.ConfigCompatibleWithStandardLibrary

type MasterData map[string]interface{}

func main() {
    testJson := `{"name": "test", "values": [{"code":"A"}, {"code":"B"}]}`

    var d MasterData

    json.Unmarshal([]byte(testJson), &d)

    fmt.Println("%s", d)

    jsonFilter := `$..[?(@.code=="B")]`

    filter, _ := jsonpath.Get(jsonFilter, d)
    filterPatched, _ := jsonpathpatch.Get(jsonFilter, d)
    fmt.Println("Without Patch: %s", filter)
    fmt.Println("With Patch: %s", filterPatched)
}

Output:

%s map[name:test values:[map[code:A] map[code:B]]]
Without Patch: %s []
With Patch: %s [map[code:B]]
generikvault commented 3 years ago

Hi tarunlalwani,

if you add a test case I can merge this. In your use case it is actually not necessary. You could simply cast d to an map:

filter, _ := jsonpath.Get(jsonFilter, map[string]interface{}(d))

That will do the trick and is faster since it doesn't require reflection.

I got a little confused with the title MasterData isn't a struct. It's just a custom type.