Get Names of Children in JSONPath - json

I wanna get children names of this JSON via JSONPath:
{
"status": "success",
"data": {
"blaze": {
"status": false
},
"fire": {
"status": true
},
"thunder": {
"status": false
}
}
}
and Output must be this:
["blaze", "fire", "thunder"]
but when i use data.*, i get incorrect and different response. I just want the correct parameter, because i'm using on several programming languages and i don't use the other referrences/functions.

Indeed data.* will return you the value of the objects inside the data object of your given array.
Your json -
{
"status": "success",
"data": {
"blaze": {
"status": false
},
"fire": {
"status": true
},
"thunder": {
"status": false
}
}
}
and the output of $.data.* expression -
[
{
"status": false
},
{
"status": true
},
{
"status": false
}
]
To just access the keys of data object you have to use ~ operator.
Using the expression $.data.*~ you will get the output as -
[
"blaze",
"fire",
"thunder"
]
Here you can test it. Credit to: This answer

Related

Json Extractor in JMeter

I am using JSON extractor in JMeter. Below is my Response Body. I am using the Json path expression to capture the value, which is working fine.
Apart from the above condition, I need to add one more condition.
If the "travelID" length is equal to 33, then only I need to get the BoundID.
Example : AAA-AB1234-AAABBB-2022-11-10-1111
Total length or count of the above travelID is 33, but sometime I used to get 31,32 also but I need to capture the Bound ID only when the length is 33. Is that feasible ? Please help on the same
PFB sample response body.
{
"data": {
"RenewalDetails": [
{
"ExpiryDetails": {
"duration": "xxxxx",
"destination": "XXX",
"from": "XXX",
"value": 2,
"segments": [
{
"valudeid": "xxx-xx6262-xxxyyy-1111-11-11-1111"
}
]
},
"Itemdetails": [
{
"BoundId": "xxx-1-xxx1-111111111111-1",
"isexpired": true,
"FamilyCode": "PREMIUM",
"availabilityDetails": [
{
"travelID": "AAA-AB1234-AAABBB-2022-11-10-1111",
"quota": "X",
"scale": "XXX",
"class": "X"
}
]
}
]
}
]
},
"warnings": [
{
"code": "xxxx",
"detail": "xxxxxxxx",
"title": "xxxxxxxx"
}
]
}
I don't think it's possible with JSON Extractor, I would rather suggest going for JSR223 PostProcessor and the following Groovy code:
def BoundId = new groovy.json.JsonSlurper().parse(prev.getResponseData())
.data.RenewalDetails[0].Itemdetails.find { itemDetail ->
itemDetail.availabilityDetails[0].travelID.length() == 33
}?.BoundId
vars.put('BoundId', BoundId ?: 'Not Found')
You will be able to refer extracted value as ${BoundId} later on where required.

pyjq - how to use "select" with both query and value as variables

I am writing a code in python3 where i am struggling with usage of variables with "pyjq", the code works without variables but variables are not getting parsed inside pyjq.
The documentation referred is https://github.com/doloopwhile/pyjq/blob/master/README.md#api
Please check the code given below and suggest -
My code
import json, os
import pyjq
from flask import Flask, request, jsonify
def query_records():
args = {"meta.antivirus.enabled": "true"}
for key, value in args.items():
with open('/tmp/data.txt', 'r') as f:
print (key)
print (value)
data = f.read()
records = json.loads(data)
query = ("." + key)
print (query)
#jq '.[]|select(.meta.antivirus.enabled=="true")' filename.json works,issue with variable substitution in python
match = pyjq.all('.[]|select(["$query"]==$value)', records, vars={"value": value,"query": query})
print (match)
query_records()
Content of file "/tmp/data.txt"
[
{
"name": "alpharetta",
"meta": {
"antivirus": {
"enabled": "true"
},
"limits": {
"cpu": {
"enabled": "true",
"value": "250m"
}
}
}
},
{
"meta": {
"allergens": {
"eggs": "true",
"nuts": "false",
"seafood": "false"
},
"calories": 230,
"carbohydrates": {
"dietary-fiber": "4g",
"sugars": "1g"
},
"fats": {
"saturated-fat": "0g",
"trans-fat": "1g"
}
},
"name": "sandwich-nutrition"
},
{
"meta": {
"allergens": {
"eggs": "true",
"nuts": "false",
"seafood": "true"
},
"calories": 440,
"carbohydrates": {
"dietary-fiber": "4g",
"sugars": "2g"
},
"fats": {
"saturated-fat": "0g",
"trans-fat": "1g"
}
},
"name": "random-nutrition"
}
]
Expected output(which works without variables)
{
"name": "alpharetta",
"meta": {
"antivirus": {
"enabled": "true"
},
"limits": {
"cpu": {
"enabled": "true",
"value": "250m"
}
}
}
}
Current output []
seems like some issue with variables not being passed in case of "query" , help would be appreciated.
Edit 1
It works if I hardcode "query" -
match = pyjq.all('.[]|select(.meta.antivirus.enabled==$value)', records, vars={"value": value,"query": query})
but not vice-versa
which probably narrows it down to issue with the variable "query"
JQ is not a necessity and I can use other libraries too,given that json is returned
Variables are intended to be used for values, not for jq expressions (at least not directly).
I think the easiest option here is to go for an fstring:
match = pyjq.all(f'.[]|select({query}==$value)', records, vars={"value": value})
and it probably makes sense to prepend the period inside the fstring:
match = pyjq.all(f'.[]|select(.{key}==$value)', records, vars={"value": value})

Can't access property from JSON file, why?

Here's the JSON:
data = {
"company_name": "חברה לדוגמה",
"audit_period_begin": "01/01/2021",
"audit_period_end": "31/12/2021",
"reports": [
{
"type": {
"he": "מאזן",
"en": "Balance Sheets"
},
"fin_statement": "BS",
"sections": [
{
"section_name": {
"he": "נכסים שוטפים",
"en": "Current Assets"
},
"totals": {
"2020": {
"final_total_local": 100000,
"final_total_foreign": 0
},
"2021": {
"final_total_local": 110000,
"final_total_foreign": 0
}
},
"subsections": [
{......(the rest is irrelevant)
and I'm trying to call:
data.reports[0].sections[0]['totals']
but I get an error:
Element implicitly has an 'any' type because expression of type '"totals"' can't be used to index type
and can't read the property, why?
After you acquire data.reports[0].sections[0].totals probably successfully you are accessing it as if it was an array, whereas it's an object. try data.reports[0].sections[0]['totals']["2020"] instead of data.reports[0].sections[0]['totals'][2020]. This is just a guess as you didn't provide enough code.

jmespath :select json object element based on other (array) element in the object

I have this JSON
{
"srv_config": [{
"name": "db1",
"servers": ["srv1", "srv2"],
"prop": [{"source":"aa"},"destination":"bb"},{"source":"cc"},"destination":"cc"},]
}, {
"name": "db2",
"servers": ["srv2", "srv2"],
"prop": [{"source":"dd"},"destination":"dd"},{"source":"ee"},"destination":"ee"},]
}
]
}
I try to build a JMESPath expression to select the prop application in each object in the main array, but based on the existence of a string in the servers element.
To select all props, I can do:
*.props [*]
But how do I add condition that says "select only if srv1 is in servers list"?
You can use the contains function in order to filter based on a array containing something.
Given the query:
*[?contains(servers, `srv1`)].prop | [][]
This gives us:
[
{
"source": "aa",
"destination": "bb"
},
{
"source": "cc",
"destination": "cc"
}
]
Please mind that I am also using a bit of flattening here.
All this run towards a corrected version of you JSON:
{
"srv_config":[
{
"name":"db1",
"servers":[
"srv1",
"srv2"
],
"prop":[
{
"source":"aa",
"destination":"bb"
},
{
"source":"cc",
"destination":"cc"
}
]
},
{
"name":"db2",
"servers":[
"srv2",
"srv2"
],
"prop":[
{
"source":"dd",
"destination":"dd"
},
{
"source":"ee",
"destination":"ee"
}
]
}
]
}

RestKit mapKeyOfNestedDictionaryToAttribute with array

I have a JSON response which looks like the sample below. I have added some comments // to emphasize my question.
I have no idea how to build the RKObjectMapping for the dynamic keys ("FieldNameA", "FieldNameB" - this could be anything) in combination with the array as the value. Each item of the array is of a type FieldResult.
I already learned how to handle varying key names here, but I don't get how I could properly map the array item type.
{
"result": {
"status": "FAILURE",
"details": {
"FieldNameA": [ // dynamic key name here, array of objects as a value
{
"details": {
"errorName": "InvalidField",
"errorNumber": 123
},
"status": "FAILURE"
}
],
"FieldNameB": [ // multiple values in this array, all of same type FieldResult
{
"details": {
"errorName": "UpdateRequired",
"errorNumber": 321
},
"status": "UPDATE_REQUIRED",
"suggestion": {
"update": "UpdatedInputValue"
}
},
{
"details": {
"errorName": "TooShort",
"errorNumber": 1
},
"status": "FAILURE"
}
]
}
}
}
Any help appreciated!