Jsonpath - Accessing array item using expression - json

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)]

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.

Copy value from grandchildren if it exists, use null otherwise

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

How to retrieve nested JSON values

I have the fallowing JSON object and I want to take the value of Microsoft.VSTS.Scheduling.RemainingWork
[
{
"id": 13,
"rev": 12,
"fields": {
"System.Id": 13,
"Microsoft.VSTS.Scheduling.RemainingWork": 32,
"Microsoft.VSTS.Scheduling.CompletedWork": 20
},
"url": "https://dev.azure.com/.../_apis/wit/workItems/13"
}
]
I am able retrieve data until some point:
console.log("object of json : ",result);
console.log("result[0] : ", result[0])
console.log("result[0].fields : ", result[0].fields)
The console output is,
But I this is not working result[0].fields.Microsoft.VSTS.Scheduling.RemainingWork
You can access data like an associative array :
result[0].fields['Microsoft.VSTS.Scheduling.RemainingWork']
You need to use
result[0].fields["Microsoft.VSTS.Scheduling.RemainingWork"]
Basically when you use
result[0].fields.Microsoft.VSTS.Scheduling.RemainingWork
each time you use a ".", you are trying to get the value from a nested object, like this -
[
{
"id": 13,
"rev": 12,
"fields": {
"System.Id": 13,
"Microsoft": {
"VSTS": {
"Scheduling": {
"RemainingWork": 32
}
}
},
"Microsoft.VSTS.Scheduling.CompletedWork": 20
},
"url": "https://dev.azure.com/.../_apis/wit/workItems/13"
}
]
which is not correct since that is not the way your data is structured.

Azure ADF - Array elements can only be selected using an integer index

Hi I am trying to select Status from Json Array in azure data factory
{
"dataRead": 2997,
"dataWritten": 2714,
"filesWritten": 1,
"sourcePeakConnections": 1,
"sinkPeakConnections": 1,
"rowsRead": 11,
"rowsCopied": 11,
"copyDuration": 3,
"throughput": 0.976,
"errors": [],
"effectiveIntegrationRuntime": "DefaultIntegrationRuntime (East US)",
"usedDataIntegrationUnits": 4,
"billingReference": {
"activityType": "DataMovement",
"billableDuration": [
{
"meterType": "AzureIR",
"duration": 0.06666666666666667,
"unit": "DIUHours"
}
]
},
"usedParallelCopies": 1,
"executionDetails": [
{
"source": {
"type": "AzureSqlDatabase",
"region": "East US"
},
"sink": {
"type": "AzureBlobStorage",
"region": "East US"
},
"status": "Succeeded",
"start": "2020-03-19T06:24:39.0666585Z",
"duration": 3,
"usedDataIntegrationUnits": 4,
"usedParallelCopies": 1,
I have tried selecting #activity('Copy data From CCP TO Blob').output.executionDetails.status.It throws an error:
'Array elements can only be selected using an integer index'.
Any way to resolve it?
executionDetails is an array, you have to set index to refer elements in it.
Please try:
#activity('Copy data From CCP TO Blob').output.executionDetails[0].status
Thank you for the reply
Yes, we have to use slicing and indexing the lists and Dictionaries
I have tried Dispensing_Unit_Master_Dim
#activity('Copy data From CCP TO Blob').output.executionDetails[0]['status'] and it works
0 and status there is no Dot

Jmeter - Using JSON Extractor for getting variables with the same name

This is my JSON:
[
{
"rooms": [
{
"name": "Name1",
"id": 148,
"isActive": true,
"properties": {
}
},
{
"name": "Name 2",
"id": 149,
"isActive": true,
"properties": {
}
},
{
"name": "Name 3",
"id": 150,
"isActive": true,
"properties": {
}
}
],
"timezone": "America\/New_York",
"name": "AnotherName",
"id": 88,
"isActive": false,
"properties": {
}
}]
In order to extract the "timezone" field I use: "$..timezone" and in return I get:
Result[0]=America/New_York
Using "$..id" will return:
Result[0]=88
Result[1]=148
Result[2]=149
Result[3]=150
The question is: Which syntax to use in order to extract only Result[0]=88 ?
I've been trying several available options but with no success.. Any ideas?
You're using .. operator which means deep scan so JMeter finds all id attributes and returns all their values.
If you want only the top-level ID for the first entry in the response JSON Array you need to explicitly set path to it like:
$.[0].id
if you need to get the id where timezone is America/New_York - the relevant JSON Path query would be:
$..[?(#.timezone == 'America/New_York')].id
More information: JMeter's JSON Path Extractor Plugin - Advanced Usage Scenarios
You can use $.[*]id to get Result[0]=88