43

I have the following JSON and I need to get the plain name value using JSONPath:

{
  "single" : {
    "id" : 1, 
    "name" : "Item name"
  }
}

Expression that I used is $.single.name but I always get an array:

[ "Item name" ]

instead of a string value ("Item name").

Ilija
  • 4,105
  • 4
  • 32
  • 46

5 Answers5

39

but I always get an array:

That is meant to happen. As you can read in this documentation, under 'Result' (almost at the bottom):

Please note, that the return value of jsonPath is an array, which is also a valid JSON structure. So you might want to apply jsonPath to the resulting structure again or use one of your favorite array methods as sort with it.

So basically it will always return an array. If you need the data as an other type, e.g. a String in this case, you will have to do the conversion yourself I'm afraid.

Tim
  • 41,901
  • 18
  • 127
  • 145
  • 2
    Yes, I got to that conclusion. Reason why I asked is to see if I am missing a bit of JSONPath syntax that will let me get the first element of the resulting array, and not an entire array. – Ilija May 13 '14 at 07:58
  • @Ilija Sadly no. However I checked the source code and it's not very complicated, perhaps you could make some modifications to have it return something else than an array when you want it to. – Tim May 13 '14 at 08:00
  • Yes, I ended up doing that (if path ends with ``~first`` it will return first element of the resulting array). Hate doing things like that, but if there was no other way… – Ilija May 13 '14 at 13:46
  • 1
    If you got here like me you probably just need to add `[*]` to the end of your JSONPath query. It flattened the array being returned for me. – austinheiman Jan 12 '21 at 17:08
  • I'm using jsonpath-plus npm package that has `wrap` property. You can read more about the implications here: https://www.npmjs.com/package/jsonpath-plus#user-content-properties:~:text=section%20for%20details.)-,wrap%20(default,-%3A%20true)%20%2D%20Whether%20or – Jan Dočkal Jun 14 '23 at 10:17
10

I was using the Java implementation of JSONPath and got to the very same issue. What worked for me was to add '[0]' to the json path string. So in your case:

$.single.name[0]

pepan
  • 678
  • 6
  • 11
  • 4
    I ran into the similar problem but with expression. I wan to get from array single object and from that object single value, but this doesnt work: `data[?(@.id==9617)][0].is_favorite` this doesnt work either `data[?(@.id==9617)].[0].is_favorite` – Petr Beneš Aug 19 '16 at 13:38
  • Provide an example of your data first. – pepan Aug 19 '16 at 21:30
  • Here it is `{state:{apiVersion:"V3_0",errorLevel:0,errorMessage:null,errorLink:null},data:[{id:94617,is_favorite:true,vip_sub_offers:[],vouchers:[{id:11613004,code:"F8JL2",offer:94617,subOffer:1613,validTo:"2016-05-20T23:59:59.000",state:"USED",stateCode:2,obtainType:"NORMAL",redirectUrl:null,phoneNumber:null,messageText:null,shopId:94614,assignTime:"2016-05-19T00:00:03.000",useTime:"2016-05-19T00:00:05.000"}]}]}` – Petr Beneš Aug 29 '16 at 11:31
  • 1
    The Java implementation can't apply the [0] after using a predicate expression. It's apparently out of spec: https://github.com/json-path/JsonPath/issues/272 – Christer B Aug 26 '19 at 14:27
  • As far as is read somewhere, there is a Java implementation in fastjason, that can handle the [0]. The implementation from Jayway can't. – Mario Eis Sep 23 '22 at 19:00
3

It depends of the library implementations in which some of them are rigid and others offer an option to make the developer smile.

Nodejs

For example in nodejs there is a npm module : https://www.npmjs.com/package/jsonpath

Which have a method called value, which does exactly what we need

jp.value(obj, pathExpression[, newValue])

Returns the value of the first element matching pathExpression. If newValue is provided, sets the value of the first matching element and returns the new value.

Java

String json = "...";
Object document = ...parse(json);
String author0 = JsonPath.read(document, "$.store.book[0].author");

As you can see author0 is a string, not an array

Source: https://github.com/json-path/JsonPath

JRichardsz
  • 14,356
  • 6
  • 59
  • 94
1

In case you got this error

"Unable to get a scalar value for expression $.yourfield"

You have just to configure the EvaluateJsonPath processor by changing the return type property value to 'json' instead of 'auto-detect'

enter image description here

Fahd Zaghdoudi
  • 141
  • 1
  • 13
0

In an Azure Bicep template, value worked for me, in extracting a single parameter from a jsonc parameter file: $.parameters.aksAgentPoolIdentityPrincipalId.value

One could fathom a guess that in my case this is used as the implementation:
https://github.com/json-path/JsonPath

straville
  • 986
  • 3
  • 15
  • 21