Parse nested json to TMap in Unreal Engine 4 - c++

I have a nested json with the following structure within UE4:
{
"boundary_points__per__cell": {
"0": [{
"x": 16.451330042628662,
"y": 2.0813326861577965
},
{
"x": 16.755262971791506,
"y": 2.0406535171257136
}
],
"1": [{
"x": -1.6378002918100634,
"y": 4.9689057223409412
},
{
"x": 0.9452331911724825,
"y": 6.1469903490163311
}
]
}
}
I tried using proposed techniques from other threads that suggest using the JsonObjectStringToUStruct. In particular I have the following structs to parse the json logic:
USTRUCT()
struct FBoundaryPoint
{
GENERATED_USTRUCT_BODY()
UPROPERTY()
int32 x;
UPROPERTY()
int32 y;
};
USTRUCT()
struct FBoundaryPoints
{
GENERATED_USTRUCT_BODY()
UPROPERTY()
TArray<FBoundaryPoint> BoundaryPoints;
};
USTRUCT()
struct FVoronoiStruct
{
GENERATED_USTRUCT_BODY()
UPROPERTY()
TMap<FString, FBoundaryPoints> boundary_points__per__cell;
};
However, although I can receive the key strings (e.g "0", "1") I am unable to extract the values of the json array. The boundary points dictionary contains only 2 keys ("0", "1") for the sake of the question. In a real scenario it will contain a lot more than the presented case.
Any help will be appreciated.

Firstly, those aren't integers, so you would probably want to use float or double instead of int32.
On the topic of why it won't parse, based on a comment by nick.shin:
the use of TMap is not applicable to JSON -- the simpler TArray must be used.
and, to give you the closest "TMap-like" functionality -- your JSON will need to look like:
{
"boundary_points__per__cell": [
{ "key":"0", "value":[{ "x":16.451330042628662, "y":2.0813326861577965 }] },
{ "key":"1", "value":[{ "x":16.755262971791506, "y":2.0406535171257136 }] }
]
}
When using JsonObjectConverter -- the engine will NOT allow you to make up a "key" name "on-the-fly" -- you need to define it so the engine can make the properties accessible as standard C++ structs (which makes it possible to setup and be used with Blueprints).
having said that, it is possible to make your own key:value pairs -- but, you will need to use the more low level TJsonWriter and TJsonWriterFactory & TJsonReader and TJsonReaderFactory functions. you will need to hold the engine's hand when you fill your own USTRUCT that may be using TMap...
and then, your custom JSON parser and writer can read something like this:
{
"MyMap": [
{ "MyKey1", { "0", "bliz" } },
{ "MyKey2", { "1", "blaz" } }
]
}

Related

ElasticSearch wildcard not returning when value has special characters

I have an elastic search service that fetches when you type into a text input to then populate a table. The search is working (returning filtered data) correctly for all alphanumeric values but not special characters (hyphens in particular). For example for the country Timor-Leste if I pass in Timor as the term I get the result but as soon as I add the hyphen (Timor-) I get an empty array response.
const queryService = {
search(tableName, field, term) {
// If there is no search term, run the wildcard search with 20 values
// for the smaller lists to be pre-populated, like "Gender"
return `
{
"size": ${term ? 200 : 20},
"query": {
"bool": {
"must": [
{
"match": {
"tablename": "${tableName}"
}
},
{
"wildcard": {
"${field}": {
"value": "${term ? `*${term.trim()}*` : '*'}",
"boost": 1.0,
"rewrite": "constant_score"
}
}
}
]
}
}
}
`;
},
};
Is there a way I can modify my wildcard request to allow hyphens? The other response I've seen on here has suggested using "analyze_wildcard": true which hasn't worked. I've also tried to manually escape by putting a \ before each hyphen with .replace.
It all boils down to Elasticsearch analyzers.
By default, all text fields will be run through the standard analyzer, e.g.:
GET _analyze/
{
"text": ["Timor-Leste"],
"analyzer": "standard"
}
This will lowercase your input, strip any special chars, and produce the tokens:
["timor", "leste"]
If you'd like to forgo this default process, add a .keyword mapping:
PUT your-index/
{
"mappings": {
"properties": {
"country": {
"type": "text",
"fields": { <---
"keyword": {
"type": "keyword"
}
}
}
}
}
}
Then reindex your docs, and when dynamically constructing the wildcard query with the newly created .keyword field, make sure the hyphen (and all other special chars) is properly escaped:
POST your-index/_search
{
"query": {
"wildcard": {
"country.keyword": {
"value": "*Timor\\-*" <---
}
}
}
}

How to read Json string starting with square brackets in it? [duplicate]

This question already has an answer here:
How to use boost::property_tree to parse JSON with array root
(1 answer)
Closed 2 years ago.
I am using c++ code to read json string to retrieve value based on specific key names. Example of my json response from web API is in array format like below.
[
{
"username": "123456",
"useraddress": "abc",
"data": [
{
"schedule": true,
"task": "abc",
"risk": "1",
}
],
"date": "0000-00-00"
}
]
Like the above format is the actual response. I have to retrieve date value using key "date".
My code snippet:
{
std::stringstream jsonString;
boost::property_tree::ptree pt;
jsonString << ws2s(Info).c_str();
boost::property_tree::read_json(jsonString, pt);
std::string date = pt.get<std::string>("date");
}
'Info' in above snippet is wsstring containing json response data.
I can able to retrieve "date" if [] square brackets are removed manually. Since it is array format, if I pass without removing brackets, read_json throws error.
Can somebody help this out?
Yeah. Boost Property Tree is a property tree library, not JSON.
You're in luck though, Boost has a JSON library now https://www.boost.org/doc/libs/1_75_0/libs/json/doc/html/index.html
Note: your input isn't valid JSON either, because JSON doesn't strictly allow trailing commas. You can enable them with an option in Boost JSON though:
Live On Compiler Explorer
#include <boost/json.hpp>
#include <iostream>
int main() {
std::string input = R"(
[
{
"username": "123456",
"useraddress": "abc",
"data": [
{
"schedule": true,
"task": "abc",
"risk": "1",
}
],
"date": "0000-00-00"
}
])";
boost::json::parse_options options;
options.allow_trailing_commas = true;
auto json = boost::json::parse(input, {}, options);
for (auto& el : json.as_array()) {
std::cout << el.at("date") << "\n";
}
}
Prints
"0000-00-00"

Amazon EventBridge: Match an object inside of an array

I've stuck the problem with defining a rule for matching my events.
Googled, tested.
Let's say, we've the following event which contains the object user in the array events:
{
"version": "0",
"...": "...",
"detail": {
"events": [
{
"user": {
"id": "5efdee60b48e7c1836078290"
}
}
]
}
}
Is there any way to match the user.id in an EventBus rule?
I've already tried to use the following rule which is not valid:
{
"detail": {
"events": [
{
"user": {
"id": [
"5efdee60b48e7c1836078290"
]
}
}
]
}
}
then,
{
"detail": {
"events[0]": {
"user": {
"id": [
"5efdee60b48e7c1836078290"
]
}
}
}
}
also no effect.
I don't want to give up, but I'm tired with it ;)
This pattern should work to match this event:
{
"detail": {
"events": {
"user": {
"id": [
"5efdee60b48e7c1836078290"
]
}
}
}
}
Today, EventBridge only supports matching simple values (string, integer, boolean, null) with an array. You can read more in the service documentation.
I did some playing around with your example but I can't make it work. Based on reading the Arrays in EventBridge Event Patterns I have to conclude that matching inside arrays with complex values is not possible.
The quote that seems to confirm this is "If the value in the event is an array, then the pattern matches if the intersection of the pattern array and the event array is non-empty."
And from the Event Patterns page "Match values are always in arrays." So if your pattern is an array and the value in the event is also an array (this is the example you gave), a "set" based intersection test is performed. Your pattern would have to match the entire array entry, not just a single field like you have in the example.

Get keys from Json with regex Jmeter

I'm hustling with regex, and trying to get the id's from this body.
But only the id´s in the members list, and not the id in the verified key. :)
To clarify, I'm using Regular Expression Extractor in JMeter
{
"id": "9c40ffca-0f1a-4f93-b068-1f6332707d02", //<--not this
"me": {
"id": "38a2b866-c8a9-424f-a5d4-93b379f080ce", //<--not this
"isMe": true,
"user": {
"verified": {
"id": "257e30f4-d001-47b3-9e7f-5772e591970b" //<--not this
}
}
},
"members": [
{
"id": "88a2b866-c8a9-424f-a5d4-93b379f780ce", //<--this
"isMe": true,
"user": {
"verified": {
"id": "223e30f4-d001-47b3-9e7f-5772e781970b" //<--not this
}
}
},
{
"id": "53cdc218-4784-4e55-a784-72e6a3ffa9bc", //<--this
"isMe": false,
"user": {
"unverified": {
"verification": "XYZ"
}
}
}
]
}
at the moment I have this regex :
("id": )("[\w-]+")
But as you can see here it returns every guid
Any ideas on how to go on?
Thanks in advance.
Since the input data type is JSON, it is recommended to use the JMeter's JSON Path Extractor Plugin.
Once you add it, use the
$.members[*].id
JSON path expression to match all id values of each members in the document that are the top nodes.
If you may have nested memebers, you may get them all using
$..members[*].id
You may test these expressions at https://jsonpath.com/, see a test:

Parsing JSON Responses Of Unknown Format For Single Value

I am creating a stock screener that sources data from ultiple apis. I would like to parse api responses from various apis for a single value.
I am using stock data apis that return JSON in different nested formats. Since the format of the JSON can be different, e.g. root could be an object or an array.. I am having trouble understanding how to go about this. I have successfully parsed JSON responses when the format is known. I am using qt, with no 3rd party libs, which seems to require that you parse these responses explcitly as I have done previously. How do I create a generic JSON parser that? Is this even possible?
Example: For this JSON response.. I would like to parse for "value"
{
"historical_data": [
{
"date": "2019-06-28",
"value": 197.92
}
],
"security": {
"id": "sec_agjrgj",
"company_id": "com_NX6GzO",
"stock_exchange_id": "sxg_ozMr9y",
"name": "Apple Inc",
"code": "EQS",
"currency": "USD",
"ticker": "AAPL",
"composite_ticker": "AAPL:US",
"figi": "BBG000B9Y5X2",
"composite_figi": "BBG000B9XRY4",
"share_class_figi": "BBG001S5N8V8"
},
"next_page": null
}
I also want to parse this JSON repsone for "value"
{
"date": "2019-06-28",
"value": 197.92
}
I am trying to not write a parser function for each api I use. I would like to be able to find if the JSON has a "value" and if so.. return its value.
You can use JsonPath for this. For example, using the jsoncons implementation of JsonPath, you can write
#include <iostream>
#include <jsoncons/json.hpp>
#include <jsoncons_ext/jsonpath/json_query.hpp>
using namespace jsoncons;
int main()
{
std::string data = /* your JSON response */;
json root = json::parse(data);
// json_query returns an array of items that match the JsonPath expression
json result = jsonpath::json_query(root, "$..value");
for (const auto& item : result.array_range())
{
std::cout << item << "\n";
}
}
Output:
197.92