JsonPath filter query syntax - json

I'm trying to write a JsonPath query that selects a specific object based on a condition, but either the syntax fails me or I fail the syntax.
Given the below Json object, how would I select the "Data" object containing Dirk Gently's details based on the fact that he uses the "Stumble" method?
{
"Investigators": [
{
"Type": "Legend",
"Object": {
"Method": "Investigate",
"Data": {
"Name": "Sherlock",
"Surname": "Holmes"
}
}
},
{
"Type": "Visionary",
"Object": {
"Method": "Stumble",
"Data": {
"Name": "Dirk",
"Surname": "Gently"
}
}
}
],
"Version": 1
}
I know that I can get to the Method-field like this:
$.Investigators..Object.Method
I assumed that something like this would work:
$.Investigators..Object[?(#.Method=="Stumble")].Data
I'm testing this using: https://jsonpath.com/ to evaluate the query - and I can't seem to get it right.
Am I trying to do something that is not achievable or am I just making a stupid mistake?

Go to this jsonpath online sandbox and try this experssion:
$.Investigators..Object[?(#.Method=="Stumble")].Data
using either the Jayway or Gatling implementations, the output will be:
[
{
"Name" : "Dirk",
"Surname" : "Gently"
}
]

Related

How to move JSON fields in mass effectively?

I have a JSON like this:
{
"array1": [
{
"data": {
"id": "1",
"name": "foo",
},
"classes": "class1"
},
{
"data": {
"id": "2",
"name": "bar",
},
"classes": "class2"
...
}
}
I want to move all the classes into data object. Using https://jsoneditoronline.org I can only do that for each object individually. I guess I can write a script to do this, but is there a built tool for this?
I don't think there will be any tool for such custom requirement. May be you can try the following script.
json.array1.forEach(arr => {
arr.data['classes'] = arr.classes;
delete arr.classes;
})
It seems that regex is the quickest way to do this. Here is how I do:
Search: ("data".*?)(}.*?)(,"classes":.*?)}
Replace: $1$3$2}

How to write JSON Path to get particular value based on string filter?

I am new to JSON Path and I am trying to get 'id' corresponding to name='Candy' using JsonPath in below JSON payload.
{
"responsePayload": [
{
"content": {
"id": "101",
"name": "Candy"
},
"links": [
{
"rel": "self",
"link": "api/v1/sweets/101",
"id": "101"
}
]
},
{
"content": {
"id": "102",
"name": "Chocolate"
},
"links": [
{
"rel": "self",
"link": "api/v1/sweets/102",
"id": "102"
}
]
}
]
}
For this I tried Jsonpath $.responsePayload[0].content[?(#.name=='Candy')].id but that is not working. I am using https://jsonpath.com/ for testing this JsonPath. Please guide me how I can achieve required result.
You're really close. You need more of the path inside the expression.
$.responsePayload[?(#.content.name=='Candy')].content.id
The [0] you have in your response isolates the first element only, but it sounds like you want to iterate over the whole array in responsePayload. To do that, the filter expression selector [?(...)] must act on that array.
Next, the # represents the current item, and you can build a full path off of it. You can see how that works above.
Finally, the filter expression selector returns the full item when the expression returns true. So you then need to navigate into .content.id again to get the value you're after.

Apache VTL - Copy node

Is there a way to do deep copy using apache VTL?
I was trying to use x-amazon-apigateway-integration using requestTemplates.
The input JSON is as shown below,
{
"userid": "21d6523137f6",
"time": "2020-06-16T15:22:33Z",
"item": {
"UserID" : { "S": "21d6523137f6" },
<... some complex json nodes here ...>,
"TimeUTC" : { "S": "2020-06-16T15:22:33Z" },
}
}
The requestTemplate is as shown below,
requestTemplates:
application/json: !Sub
- |
#set($inputRoot = $input.path('$'))
{
"TableName": "${tableName}",
"ConditionExpression": "attribute_not_exists(TimeUTC) OR TimeUTC > :sk",
"ExpressionAttributeValues": {
":sk":{
"S": "$util.escapeJavaScript($input.path('$.time'))"
}
},
"Item": "$input.path('$.item')", <== Copy the entire item over to Item.
"ReturnValues": "ALL_OLD",
"ReturnConsumedCapacity": "INDEXES",
"ReturnItemCollectionMetrics": "SIZE"
}
- {
tableName: !Ref EventsTable
}
The problem is, the item gets copied like,
"Item": "{UserID={S=21d6523137f6}, Lat={S=37.33180957}, Lng={S=-122.03053391}, ... other json elements..., TimeUTC={S=2020-06-16T15:22:33Z}}",
As you can see, the whole nested json become a single atribute. While I expected it to become a fully blown json node on its own like below,
"Item": {
"UserID" : { "S": "21d6523137f6" },
"Lat": { "S": "37.33180957" },
"Lng": { "S": "-122.03053391" },
<.... JSON nodes ...>
"TimeUTC" : { "S": "2020-06-20T15:22:33Z" }
},
Is it possible to deep/nested copy operation on a json node like above without doing the kung-fu of iterating the node and appending the childs o a json node variable etc...
btw, I'm using AWS API Gateway request template, so it may not support all the Apache VTL templating options.
You need to use the $input.json method instead of $input.path.
"Item": $input.json('$.item'),
Note that I removed the double quotes.
If you had the double quotes because you want to stringify $.item, you can do that like so:
"Item": "$util.escapeJavaScript($input.json('$.item'))",

How to remove one property from json input message using replace() expression in azure logic app?

{
"metadata": {
"id": "2",
"uri": "3",
"type": "2"
},
"Number": "2323600002913",
"Date": "04/21/2009",
"postingDate": "00/00/0000",
"ata": {
"results": [
{
"metadata": {
"id": "r",
"uri": "e2",
"type": "s2"
},
"item": "000010",
"data":"ad"
}
]
}
}
want to remove metadata property from above json message and output should be like below
{
"Number": "2323600002913",
"Date": "04/21/2009",
"postingDate": "00/00/0000",
"ata": {
"results": [
{
"item": "000010",
"data":"ad"
}
]
}
}
I tried with removeProperty() which is working for root level metadata but inside metadata not removed.
how to use replace() in this case or anything else to only remove metadata.
The simplest way is use inline code, cause even with removeProperty() expression to remove the metadata under results, it will return the results array data not the whole json data. Then you will have to combine them, it's not a convenient way.
And with inline code you could refer to my below picture. The variable json is the value from triggerbody, then just delete the node or key and return the json variable. And with this way, even you want to delete many metadata in the array, you could add a for loop to delete it, just think of it as plain js code.
Update:if you want to get value from variable,cause no support expression to get value from variable so use the below expression.
var json =wworkflowContext.actions.Initialize_variable.inputs.variables[0].value;
And about how to loop the array in the json refer to my below pic.

json schema for a map of similar objects

I wish to write a json schema to cover this (simplified) example
{
"errorMessage": "",
"nbRunningQueries": 0,
"isError": False,
"result": {
"foo": {"price":10.0, "country":"UK"},
"bar": {"price":100.2, "country":"UK"}
}
}
which can have this pretty trivial root schema
schema = {
"type":"object",
"required":True,
"properties":{
"errorMessage": {"type":"string", "required":True},
"isError": {"type":"boolean", "required":True},
"nbRunningQueries": {"type":"number", "required":True},
"result": {"type":"object","required":True}
}
}
The complication is the results {} element. Unlike a standard pattern where results would be an array of same objects - each with an id field or similar this response models a python dictionary which looks like this:
{
"foo": {},
"bar": {},
...
}
So given that a will be getting a results object of flexible size with no set keys how can I write json schema for this?
I don't control the input sadly or I'd rewrite it to be something like
{
"errorMessage": "",
"nbRunningQueries": 0,
"isError": False,
"result": [
{"id": "foo", "price":10.0, "country": "UK"},
{"id": "bar", "price":100.2, "country":"UK"}
]
}
Any help or links to pertinent examples would be great. Thanks.
With json-schema draft 4, you can use additionalProperties keyword to specify the schema of any new properties that you could receive in your results object.
"result" : {
"type" : "object"
"additionalProperties" : {
"type" : "number"
}
}
If you can restrict the allowed key names, then you may use "patternProperties" keyword and a regular expression to limit the permited key names.
Note that in json-schema draft 4 "required" must be an array which is bounded to the object, not to each property.