Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jsonpath for length of array

Given json such as

{"arr1" : [1,2,3], "arr2" : []}

where it is known that there are arrays named arr1 and arr2, is there a jsonpath expression for the length of an array that will work for both empty and non-empty arrays?

I have made several attempts using google code's JsonPath library, of note:

JsonPath.read(json, "arr1.length")

but it gives an error saying that arrays have no attributes.

I am looking for a single string path that resolves to an array's length, not a subsequent call to an intermediate, eg

JsonPath.read(json, "arr1").length // useless to me

Any level of complexity of expression is acceptable.

For context, I want to feed a test suit with path/value pairs, which works great for values, but I can't assert array size with this pattern.

like image 855
Bohemian Avatar asked Jul 16 '14 08:07

Bohemian


2 Answers

If the length of an array is required only for assertion then json-path-assert artifact can be used in conjunction with JsonPath. Here is a sample written in Groovy:

@Grab('com.jayway.jsonpath:json-path:0.9.1')
@Grab('com.jayway.jsonpath:json-path-assert:0.9.1')

import com.jayway.jsonpath.JsonPath
import static com.jayway.jsonassert.JsonAssert.*
import static org.hamcrest.MatcherAssert.assertThat
import static org.hamcrest.Matchers.*

def json = /{ "arr1": [1,2,3], "arr2": [] }/

with(json).assertThat( "arr1", hasSize(3) )
          .assertThat( "arr2", hasSize(0) )
          .assertThat( "arr2", emptyCollection() )

Verify that assertion fails with different size of array. Best part is the use of Hamcrest's Matcher API which opens door to flexible and wide variety of assertions.

Length cannot be obtained from the path expression AFAIK.

like image 158
dmahapatro Avatar answered Sep 20 '22 00:09

dmahapatro


@dmahapatro is right stating that

Length cannot be obtained from the path expression

But if you only need it to access some specific element (let's say the last element of an array), you could still use :

{"arr1": [1,2,3], "arr2": [{"name": "a"}, {"name": "b"}]}
arr1[(@.length-1)]       // returns "3"
arr2[(@.length-1)].name  // returns "b"

You can also do more advanced requests, but for that i suggest you take a look at the plugin's documentation.

like image 42
Xeltor Avatar answered Sep 18 '22 00:09

Xeltor