KarateException Missing Property in path - JSON - json

I was trying to match particular variable from response and tried as below. But im getting error saying KarateException Missing Property in path $['Odata']. My question is: how we can modify so that we won't get this error?
Feature:
And match response.#odata.context.a.b contains '<b>'
Examples:
|b|
|b1 |
|b2 |
Response is
{
"#odata.context": "$metadata#Accounts",
"a": [
{
"c": 145729,
"b": "b1",
"d": "ON",
},
{
"c": 145729,
"b": "b2",
"d": "ON",
}
]
}

I think you are confused with the structure of your JSON. Also note that when the JSON key has special characters, you need to change the way you use them in path expressions. You can try paste the below in a new Scenario and see it work:
* def response =
"""
{
"#odata.context": "$metadata#Accounts",
"a": [
{
"c": 145729,
"b": "b1",
"d": "ON",
},
{
"c": 145729,
"b": "b2",
"d": "ON",
}
]
}
"""
* match response['#odata.context'] == '$metadata#Accounts'
* match response.a[0].b == 'b1'
* match response.a[1].b == 'b2'

Related

How do I collect values by keys from different levels in JQ?

Let's suppose I have a JSON like this:
[
{
"a": 1,
"l": [
{"b": "z"},
{"b": "x"}
]
},
{
"a": 2,
"l": [
{"b": "c"}
]
}
]
I want to collect the data from all embedded arrays and to get an array of all objects with "a" and "b" values. For the JSON above the result should be:
[
{"a": 1, "b": "z"},
{"a": 1, "b": "x"},
{"a": 2, "b": "c"}
]
What JQ expression do I need to try to solve the issue?
You can use .l[] within the expression in order to return each element of the array returned in the response. So, use this one below
map({a} + .l[])
Demo

Conditional deletion from array of field A with condition on field B

Let's say I have a json with an array inside. Say that the elements of this array are objects with keys A and B. I would like to remove the B objects on the elements where A objects meet a certain condition.
For example, I would like to remove the B objects where A is greater than 5, transforming
{
"title": "myTitle",
"myArray": [
{
"A": 1,
"B": "foo"
},
{
"A": 4,
"B": "bar"
},
{
"A": 7,
"B": "barfoo"
},
{
"A": 9,
"B": "foobar"
}
]
}
into
{
"title": "myTitle",
"myArray": [
{
"A": 1,
"B": "foo"
},
{
"A": 4,
"B": "bar"
},
{
"A": 7
},
{
"A": 9
}
]
}
The task seems easy enough and if I had't have to keep the A's it would be a simple del(select..) thing. There surely must be an elegant way to do this as well?
Thank you!
You can still use a del(select..) thing.
.myArray[] |= del(select(.A > 5) .B)
demo at jqplay.org

How can I convert to Json Object to Json Array in Karate?

I want to convert Json Object to Json Array in Karate to use 'match each' func.
I am getting to ('match each' failed, not a json array) error when I use match each func with Json Object.
Here is My Json Object:
{
{ "a": "q"
"b": "w",
"c": "t"
},
{ "a": "x"
"b": "y",
"c": "z"
}
}
And here is what I need:
[
{
{ "a": "q"
"b": "w",
"c": "t"
},
{ "a": "x"
"b": "y",
"c": "z"
}
}
]
Try this approach, using embedded expressions: https://github.com/intuit/karate#embedded-expressions
* def foo = { a: 1 }
* def list = [ '#(foo)' ]
* match each list == foo

jq update list elements based on values

Is it possible to use jq to turn the following JSON data
[
{
"a": null,
"b": [
{
"c": "cc",
"d": "dd1"
},
{
"c": "cc",
"d": "dd1",
"e": "ee",
"f": "ff"
}
]
},
{
"b": [
{
"c": "cc",
"d": "dd2",
"e": "ee",
"f": "ff"
}
]
}
]
into
[
{
"a": null,
"b": [
[
"cc", "d1"
],
[
"cc", "d1", "ff"
]
]
},
{
"b": [
[
"cc", "d2", "ff"
]
]
}
]
?
Note that the purpose is to reduce the b list with certain elements of its items based on a condition. The condition assigns the string d1 if the value of d is dd1, otherwise d2 is assigned if dd2 is present.
The following unsuccessful attempt demonstrates the idea:
$ jq -r '.[].b[] = [.[].b[].c, ?, .[].b[].f?]'
This is probably not the best way to do what you want, but it does get the desired output and it has the conditional you asked about.
jq '.[].b |= map(
[ .c,
(if .d == "dd1" then "d1" elif .d == "dd2" then "d2" else . end),
.f // empty
] )'
Without changing the value of the d key, you would use this jq filter:
jq '.[].b[]|=(to_entries|map(.value))' file
That updates the b array into all values of the inner objects.
If you want to update the d, you could use this filter:
jq '.[].b[] |= (to_entries|
map(
if(.key=="d") then
.value|=sub("d+";"d")
else .
end
|.value)
)' file
that adds a check if the key is d the associated value is updated to remove the duplicated d character from the string. This requires jq to support for regex (to be able to use the sub function).

Snakemake : multi-level json parsing

I've a json configuration file that looks like:
{
"projet_name": "Project 1",
"samples": [
{
"sample_name": "Sample_A",
"files":[
{
"a": "file_A_a1.txt",
"b": "file_A_a2.txt",
"x": "x1"
},
{
"a": "file_A_b1.txt",
"b": "file_A_b2.txt",
"x": "x1"
},
{
"a": "file_A_c1.txt",
"b": "file_A_c2.txt",
"x": "x2"
}
]
},
{
"sample_name": "Sample_B",
"files":[
{
"a": "file_B_a1.txt",
"b": "file_B_a2.txt",
"x": "x1"
},
{
"a": "file_B_b1.txt",
"b": "file_B_b2.txt",
"x": "x1"
}
]
}]
}
I'm currently writing a snakemake file to process such json file. The idea is to for each sample (e.g. Sample_A , Sample_B) to concatenate the files that have the same "x" entry. For example in Sample_A, I would like to concatenate "a" files : file_A_a1.txt and file_A_b1.txt as they have the same "x" entry. Same for "b" files : file_A_a2.txt and file_A_b2.txt. file_A_c1.txt and file_A_c2.txt will not be concatenate with other files as they have a unique "x". At the end I would like a structure like this :
merged_files/Sample_A_a_x1.txt
merged_files/Sample_A_b_x1.txt
merged_files/Sample_A_a_x2.txt
merged_files/Sample_A_b_x2.txt
merged_files/Sample_B_a_x1.txt
merged_files/Sample_B_b_x1.txt
My issue is the grouping of files with same "sample_name" and same "x" .. Any suggestions ?
Thank you