Copy value from grandchildren if it exists, use null otherwise - json

Given the JSON:
{
"id": 1,
"coding": [{
"code": 1234,
"system": "target"
}, {
"code": 5678,
"system": "other"
}]
}
I can select the value of "code" where the "system" is "target", thus:
{id: .id} + {"code": .coding[]? | select(.system=="target").code}
To produce:
{
"id": 1,
"code": 1234
}
But if the object whose "system" value is "target" does not exist in the array, thus:
{
"id": 1,
"coding": [{
"code": 5678,
"system": "other"
}]
}
I want the following result:
{
"id": 1,
"code": null
}
However, my above jq produces an empty object. How can I achieve what I want?

The select built-in yields empty unless at least one of its inputs meets the given criteria, and empty consumes almost anything around itself. Hence the empty result.
Instead, use the first built-in for alternating between the code value from the object where system is target, and null. This also covers some other cases you didn't mention explicitly.
{ id, code: first((.coding[]? | select(.system == "target") .code), null) }
Online demo

Related

Delete duplications in JSON file

I am trying to reedit json file to print only subgroups that has any attributes marked as "change": false.
Json below:
{"group":{
"subgroup1":{
"attributes":[
{
"change":false,
"name":"Name"},
{
"change":false,
"name":"SecondName"},
],
"id":1,
"name":"MasterTest"},
"subgroup2":{
"attributes":[
{
"change":true,
"name":"Name"
},
{
"change":false,
"name":"Newname"
}
],
"id":2,
"name":"MasterSet"},
}}
I was trying to use command:
cat test.json | jq '.group[] | select (.attributes[].change==false)
which produce needed output but with duplicates. Can anyone help here? Or shall I use different command to achieve that result?
.attributes[] iterates over the attributes, and each iteration step produces its own result. Use the any filter which aggregates multiple values into one, in this case a boolean with the meaning of "at least one":
.group[] | select(any(.attributes[]; .change==false))
{
"attributes": [
{
"change": false,
"name": "Name"
},
{
"change": false,
"name": "SecondName"
}
],
"id": 1,
"name": "MasterTest"
}
{
"attributes": [
{
"change": true,
"name": "Name"
},
{
"change": false,
"name": "Newname"
}
],
"id": 2,
"name": "MasterSet"
}
Demo
Looks to me like the duplicate is NOT a duplicate, but a condition arising from a nested sub-grouping, which gives the appearance of a duplicate. You should look to see if there is a switch to skip processing sub-groups when the upper-level meets the condition, thereby avoiding the perceived duplication.

how to remove [] character at extracted json using json path

{
"responseCode": "200",
"data": {
"sequence": 1,
"used": true,
"sensingTags": [
{
"code": "LED",
"value": 1,
"updatedOn": 1587557350251
}
]
}
}
My goal is get updatedOn value from this json using jsonPath like this
1587557350251
i thought below jsonPath will work but it extract only empty list.
$..sensingTags[?(#.code == 'LED')][0].updatedOn
And i want to know how to extract value like below
{
"code": "LED",
"value": 1,
"updatedOn": 1587557350251
}
Not like this one.
[
{
"code" : "LED",
"value" : 1,
"updatedOn" : 1587557350251
}
]
As per Getting a single value from a JSON object using JSONPath, JsonPath will always return an array (or a false) at that point...
Best you can do is process it as an array of updatedOn and simply always grab the first value.
$..sensingTags[?(#.code == 'LED')].updatedOn

Jsonpath - Accessing array item using expression

I am using AWS Step Functions which utilizes JSONPath for providing JSON paths. I have the following input :
{
"response": {
"isSuccess": true,
"error": "",
"body": {
"count": 2,
"fields": [
{
"fieldId": 1,
"tabId": 100,
"title": "First Name"
},
{
"fieldId": 2,
"tabId": 100,
"title": "Last Name"
}
]
}
},
"iteration": {
"totalCount": 2,
"currentCount": 0,
"step": 1
}
}
I want to query the fields array as:
$.response.body.fields[$.iteration.currentCount]
The value of currentCount is incremented by 1 as part of an iteration.
I am getting an invalid XPath exception when trying to use the above.
Can someone please advice on how to provide a dynamic property value to read array values?
As described on https://github.com/json-path/JsonPath#operators you can index an array with a number only. However, you can use a filter expression to select a specific item from the array as follows.
Assuming you have another field that denotes the index such as:
{
"index": 0,
"fieldId": 2,
"tabId": 100,
"title": "Last Name"
}
You can then do
$.response.body.fields[?(#.index==$.iteration.currentCount)]

How do I give a where clause or condition to get a value in json response using rest asssured

I need to extract the value of id where name == 'abc'. How can I do that?
here is the example of response:
{
"Text": [
{
"id": "123",
"name": "ABC"
},
{
"id": "456",
"name": "XYZ"
},
{
"id": "789",
"name": "DEF"
}
]
}
So I need to extract the value of id where name =='ABC' should return me id value as 123.
I need to use jayway restassured.
Use GPath findAll feature
when().
get("/restapi").
then().
body("text.findAll{ it.name == 'ABC' }.id", hasItem("123"));

How to search nested JSON in MySQL

I am using MySQL 5.7+ with the native JSON data type. Sample data:
[
{
"code": 2,
"stores": [
{
"code": 100,
"quantity": 2
},
{
"code": 200,
"quantity": 3
}
]
},
{
"code": 4,
"stores": [
{
"code": 300,
"quantity": 4
},
{
"code": 400,
"quantity": 5
}
]
}
]
Question: how do I extract an array where code = 4?
The following (working) query has the position of the data I want to extract and the search criterion hardcoded:
SELECT JSON_EXTRACT(data_column, '$[0]')
FROM json_data_table
WHERE data_column->'$[1].code' = 4
I tried using a wildcard (data_column->'$[*].code' = 4) but I get no results in return.
SELECT row FROM
(
SELECT data_column->"[*]" as row
FROM json_data_table
WHERE 4 IN JSON_EXTRACT(data_column, '$[*].code')
)
WHERE row->".code" = 4
... though this would be much easier to work with if this wasn't an unindexed array of objects at the top level. You may want to consider some adjustments to the schema.
Note:
If you have multiple rows in your data, specifying "$[i]" will pick that row, not the aggregate of it. With your dataset, "$[1].code" will always evaluate to the value of code in that single row.
Essentially, you were saying:
$ json collection
[1] second object in the collection.
.code attribute labeled "code".
... since there will only ever be one match for that query, it will always eval to 4...
WHERE 4 = 4
Alternate data structure if possible
Since the entire purpose of "code" is as a key, make it the key.
[
"code2":{
"stores": [
{
"code": 100,
"quantity": 2
},
{
"code": 200,
"quantity": 3
}
]
},
"code4": {
"stores": [
{
"code": 300,
"quantity": 4
},
{
"code": 400,
"quantity": 5
}
]
}
]
Then, all it would require would be:
SELECT datacolumn->"[code4]" as code4
FROM json_data_table
This is what you are looking for.
SELECT data_column->'$[*]' FROM json_data_table where data_column->'$[*].code' like '%4%'.
The selected data will have [] around it when selecting from an array thus data_column->'$[*].code' = 4 is not possible.