JSONPath: Extracting subset of array produces weird results

Tags: , , ,



I have this json:

{
  "push": {
    "changes": [
      {
        "commits": [
          {
            "hash": "b194ab92186b94de3f9493818c353e9bbedb38d4"
          }
        ]
      }
    ]
  }
}

And, I have the follow jq, code that works fine

cbongiorno at 5cg6203867 in ~/dev/sterling/pipeaas on master [+!?]
$ jq -re '.push.changes[].commits[].hash ' push.json # golden hash
b194ab92186b94de3f9493818c353e9bbedb38d4

which produces what I want.

I now try to use the JSONPath equivalent and this is where it gets strange: If I try it here, I get and array size 1 with my hash:

$.push.changes[*].commits[*].hash
[
  "b194ab92186b94de3f9493818c353e9bbedb38d4"
]

So, that that yields and array, then I can just index that array, right?:

$.push.changes[*].commits[*].hash[0]
[
  "b"
]

I get the letter b – so now it’s treating the string as a character array.

So, maybe it’s an implementation problem. I tried this same path expression in groovy and I get something yet also different:

in jsonpath.groovy

@Grab(group = 'com.jayway.jsonpath', module = 'json-path', version = '2.4.0')
import com.jayway.jsonpath.*

stuff = JsonPath.parse(new File('push.json')).read('$.push.changes[*].commits[*].hash')
println(stuff)
$ groovy jsonpath.groovy

[b194ab92186b94de3f9493818c353e9bbedb38d4]

Ok, we have our array again. Now, let’s get that 1 element:

@Grab(group = 'com.jayway.jsonpath', module = 'json-path', version = '2.4.0')
import com.jayway.jsonpath.*

stuff = JsonPath.parse(new File('push.json')).read('$.push.changes[*].commits[*].hash[0]')
println(stuff)
$ groovy jsonpath.groovy 
[]

So now, it’s like the array has nothing at all?!

So, how do I get this single array item as a path expression?

Answer

You can use:

$.push.changes[0].commits[0].hash

To get the “first” hash in that hierarchy.

[*] behaves like the spread-operator in Groovy



Source: stackoverflow