String Interpolation in Keys in Jsonnet - json

I'm wondering if it's possible to have string interpolation in keys when using jsonnet?
For example, I want to do something like this:
{
std.format("Hello %03d", 12): "milk"
}
But it results in
STATIC ERROR: arith.jsonnet:2:5: expected token OPERATOR but got "."
I know the 'key' itself is valid, because if I don't use interpolation it works fine, i.e.
{
"milk": std.format("Hello %03d", 12),
"Hello 12": "milk"
}
generates:
{
"Hello 12": "milk",
"milk": "Hello 012"
}
It also looks like I can't use variables in keys, as they get resolved as just a string (not the variable's value) - any suggestions would be appreciated.

For computed field names, you need to wrap them with [] (see https://jsonnet.org/learning/tutorial.html#computed_field_names ), i.e. below will just work:
{
[std.format("Hello %03d", 12)]: "milk"
}

Related

jsonPath - how to filter results by matching substring

I have a structure like this:
{"payload": {
"Item1": {
"property1": "Sunday",
"property2": "suffering_8890"
},
"Item2": {
"property1": "Monday",
"property2": "misery_0776"
},
"Item3": {
"property1": "Tuesday",
"property2": "pain_6756"
}
}
}
I need the property2 value that contains a certain sub-string (i.e- "misery"). Ultimately I just need the 4-digit code, but even getting the full value will work. I am able to get a list of all the property2 values by using:
$..property2
This returns:
Result[0] = suffering_8890
Result[1] = misery_0776
Result[2] = pain_6756
How do I filter it so that it only gives me the result containing the substring "misery"?
With regards to full value you can use a Filter Operator like:
$..[?(#.property2 =~ /misery.*?/i)].property2
Demo:
You can extract the 4-digit value out of the variable using Regular Expression Extractor
If you want to do this in one shot:
Add JSR223 PostProcessor as a child of the request which returns above JSON
Put the following code into "Script" area
vars.put('misery', ((com.jayway.jsonpath.JsonPath.read(prev.getResponseDataAsString(), '$..[?(#.property2 =~ /misery.*?/i)].property2').get(0) =~ ('(\\d+)'))[0][1]))
Refer the extracted value as ${misery} where required
More information: Apache Groovy - Why and How You Should Use It
You can use a regular expression extractor as well for the mentioned scenario to fetch the four-digit as below
property2": "misery_(.*)"
This will help you to save the four-digit code in JMeter variables right away. If you insist you to find out the required value from JSON using jsonpath, you can use JSON filter as below :-
$..[?(#.property2.indexOf('misery')>=0)]..property2

What's the difference between the 'originalText' and 'word' keys in a token?

When using CoreNLPParser from NLTK with CoreNLP Server, the resulting tokens contain both an 'originalText' key and a 'word' key.
What's the difference between the two? Is there any documentation about them?
I've only found this issue, which mentioned the origintalText key, but it doesn't answer my questions.
from nltk.parse.corenlp import CoreNLPParser
corenlp_parser = CoreNLPParser('http://localhost:9000', encoding='utf8')
text = u'我家没有电脑。'
result = corenlp_parser.api_call(text, {'annotators': 'tokenize,ssplit'})
print(result)
prints
{
"sentences":[
{
"index":0,
"tokens":[
{
"index":1,
"word":"我家",
"originalText":"我家",
"characterOffsetBegin":0,
"characterOffsetEnd":2
},
{
"index":2,
"word":"没有",
"originalText":"没有",
"characterOffsetBegin":2,
"characterOffsetEnd":4
},
{
"index":3,
"word":"电脑",
"originalText":"电脑",
"characterOffsetBegin":4,
"characterOffsetEnd":6
},
{
"index":4,
"word":"。",
"originalText":"。",
"characterOffsetBegin":6,
"characterOffsetEnd":7
}
]
}
]
}
Update:
It seems the Token implements HasWord and HasOriginalText
A word is transformed a little bit to make it, e.g., possible to print it in an S-Expression (i.e., a parse tree). So, parentheses and other braces become tokens like -LRB- (left round brace). In addition, quotes are normalized to be backticks (``) and forward ticks ('') and some other little things.
originalText, by contrast, is the literal original text of the token that can be used to reconstruct the original sentence.

How to validate Sub-Sets of JSON Keys using match contains when there are nested JSON's in the response

From a response, I extracted a subset like this.
{
"base": {
"first": {
"code": "1",
"description": "Its First"
},
"second": {
"code": "2",
"description": "Its Second"
},
"default": {
"last": {
"code": "last",
"description": "No"
}
}
}
}
If I need to do a single validation using And match X contains to check
Inside first the Code is 1
Inside default-last the code is last?
Instead of using json path for every validation, I am trying to extract a specific portion and validate it. If there is no nested json paths, I can do it very easily using And match X contains, however when there are nested jsons, I am not able to do it.
Does this work for you:
* def first = get[0] response..first
* match first.code == '1'
* def last = get[0] response..default.last
* match last.code == 'last'
Edit: ok looks like you want to condense into one line as far as possible, more importantly to be able to do contains in nested nodes. Personally, I find this sometimes to be not worth the trouble, but here goes.
Refer also to these short-cuts: https://github.com/intuit/karate#contains-short-cuts
* def first = { code: "1" }
* match response.base.first contains first
* match response.base contains { first: '#(^first)' }
* def last = { code: 'last' }
* match response.base contains { first: '#(^first)', default: { last: '#(^last)' } }
Mhmm, My question is slightly different I think.
For example if I directly point to the first using a json path and save it to a variable savedResponse, I can do this validation
And match savedResponse contains {code: "1"}
If there were 10 Key value combinations under first and if I need to validate 6 of those, I can use the same json path and I can easily do it using match contains
Similiar way if I save the above response to a variable savedResponse, how I can validate mutliple things using match contains, in this. The below statement will not work anyway.
And match savedResponse contains {first:{code:"1"}, last:{code:"last"}}
However if I modify something will it work?

What do I call the object-hierarchical "path" of JSON attributes / properties / members and what is their standardized name?

Consider I have following typed JSON objects:
Parent: {
"field1" : "Value of field1"
"fieldC" : {Child}
}
Child: {
"field2" : "Value of field2"
}
Q: What do I call field1 and field2?
Just Strings?
Q: What to i call the "path" fieldC.field2?
Accessor path?
Field path?
Member hierarcy path?
field1 and field2 are just strings.
[anything, ..., ... ] is just an array, so the elements of an object.
and then you have 0-9 (with decimals, negative, positive or with e), true/false and null, as numeric values, boolean and nullvalue
{Child} is an object. I don't think it's called path (I'd say that's opinion-based). maybe field-path, but it's rather a child-object. the key is a string and the value is an object/array/string/bool/null/numeric or decimal
all the possibilities e.g.:
{
"string": "string-value",
"nulltype": null,
"child_object": {
"boolean": true,
"any_decimal_int": -1.5e3
},
"array_values":[
{
"any_value": true
},
{
"any_value": false
}
]
}
of course you can combine more and have unlimited child-objects and lists :)
jsonapi.org seems to refer field1,fieldC,and field2 as member names, which I find much more descriptive than just 'Strings'.
As mentioned in my comment to first answer, I guess I'll personally be using (hierarchical) property path or just (object) member hierarchy while referring to 'writing open' the object-hierarchical property/attribute/member 'path' such as fieldC.field2. Seems to be alot of room for interpretation in that. : ]

boost access float array from JSON data

I have some JSON data collected via boost and I can not work out how to access some of the data that is in an array:
JSON data : {"dvm_gnd": {"num" : 4, "value": [1,2,3,4]}, "xx_gn" : {"num : 1, "value": 5}}
I can easily get the "num" and single "value" (5) out using:
BOOST_FOREACH(ptree::value_type &v, pt) {
float value = v.second.get<float>("value")
}
However I have no idea how to access the elements of the array out? What does the ptree.get() return?
Thanks
Ross
Try this:
BOOST_FOREACH(ptree::value_type &v, pt.get_child("dvm_gnd.value")) {
float value = v.second.data();
}
I'm sure you've moved on by now, but in case someone else comes across this, ptree puts those array values as children with a blank name, so the code you want looks something like:
BOOST_FOREACH(const ptree::value_type &v, pt.get_child("dvm_gnd.value")) {
float value = v.second.get<float>("");
}
Or you can use the optional or default value version of get