Extracting Multiple Fields
UNC1739 opened this issue · 2 comments
Does the JSONPath implementation within the OJG library support extracting multiple values from different keys within the same JSONPath query? I haven't been able to find a way to do this using the library, unfortunately. I've got a quick example I can provide if that helps.
Below is some example JSON data that contains information about an AWS S3 bucket.
{
"accountId": "192547438240",
"additionalDetails": {
"ResourceDescription": {
"Identifier": "elasticbeanstalk-us-east-1-192547438240",
"Properties": {
"BucketName": "elasticbeanstalk-us-east-1-192547438240",
"RegionalDomainName": "elasticbeanstalk-us-east-1-192547438240.s3.us-east-1.amazonaws.com",
"DomainName": "elasticbeanstalk-us-east-1-192547438240.s3.amazonaws.com",
"WebsiteURL": "http://elasticbeanstalk-us-east-1-192547438240.s3-website-us-east-1.amazonaws.com",
"DualStackDomainName": "elasticbeanstalk-us-east-1-192547438240.s3.dualstack.us-east-1.amazonaws.com",
"Arn": "arn:aws:s3:::elasticbeanstalk-us-east-1-192547438240"
}
},
"TypeName": "AWS::S3::Bucket"
},
"region": "ap-northeast-3",
"resource": {
"Identifier": "elasticbeanstalk-us-east-1-192547438240",
"Properties": "{\"BucketName\":\"elasticbeanstalk-us-east-1-192547438240\"}"
},
"type": "AWS::S3::Bucket"
}
I've written the following JSONPath query to extract this data:
$.additionalDetails.ResourceDescription.Properties[WebsiteURL,DualStackDomainName]
I've found using an online JSONPath tool (jsonpath.com) that this query when run against the previously provided sample data produces the following result:
[
"http://elasticbeanstalk-us-east-1-192547438240.s3-website-us-east-1.amazonaws.com",
"elasticbeanstalk-us-east-1-192547438240.s3.dualstack.us-east-1.amazonaws.com"
]
However, when using the OJG library I'm not getting any results back from this JSONPath query. Below is the sample code I'm using:
package main
import (
"fmt"
"reflect"
"github.com/ohler55/ojg/jp"
"github.com/ohler55/ojg/oj"
)
func main() {
obj, _ := oj.ParseString(`{
"accountId": "192547438240",
"additionalDetails": {
"ResourceDescription": {
"Identifier": "elasticbeanstalk-us-east-1-192547438240",
"Properties": {
"BucketName": "elasticbeanstalk-us-east-1-192547438240",
"RegionalDomainName": "elasticbeanstalk-us-east-1-192547438240.s3.us-east-1.amazonaws.com",
"DomainName": "elasticbeanstalk-us-east-1-192547438240.s3.amazonaws.com",
"WebsiteURL": "http://elasticbeanstalk-us-east-1-192547438240.s3-website-us-east-1.amazonaws.com",
"DualStackDomainName": "elasticbeanstalk-us-east-1-192547438240.s3.dualstack.us-east-1.amazonaws.com",
"Arn": "arn:aws:s3:::elasticbeanstalk-us-east-1-192547438240"
}
},
"TypeName": "AWS::S3::Bucket"
},
"region": "ap-northeast-3",
"resource": {
"Identifier": "elasticbeanstalk-us-east-1-192547438240",
"Properties": "{\"BucketName\":\"elasticbeanstalk-us-east-1-192547438240\"}"
},
"type": "AWS::S3::Bucket"
}`)
//
x, _ := jp.ParseString("$.additionalDetails.ResourceDescription.Properties[WebsiteURL,DualStackDomainName]")
ys := x.Get(obj)
fmt.Println("ys =", ys)
fmt.Println("reflect.TypeOf(ys) = ", reflect.TypeOf(ys))
}
Below is the output from running this program:
➜ test-ojg-jsonpath go build main.go
➜ test-ojg-jsonpath ./main
ys = []
reflect.TypeOf(ys) = []interface {}
➜ test-ojg-jsonpath
My interpretation of one of the early (maybe original) description of JSONPath (https://goessner.net/articles/JsonPath) is that the element in a union can be either numbers which are treated as indexes or names which would be quoted. I know the owner of the jsonpath.com domain has a nice evaluator but that does not make it a standard. There is quite a range of interpretations of what JSONPath is as you can see from https://cburgmer.github.io/json-path-comparison. Anyway to cut the story short, the way OjG expects a union like you want would be:
$.additionalDetails.ResourceDescription.Properties['WebsiteURL','DualStackDomainName']
I did not test with your example but there are similar, albeit simpler, tests in the jp/get_test.go file.