How to parse JSON data with custom object names? - json

I want to parse a JSON with Typescript, where object names can vary and I have no way to know them all. For example:
{
"planets": {
"Alderaan": {
"available_items": {
"Cinamone": {
"available": 74,
"buy_price": 6,
"sell_price": 6
},
"Dwimeryt": {
"available": 42,
"buy_price": 12,
"sell_price": 11
}
}
}
}
Where there can be many planets with different names.
I figured out that in order to parse JSON object successfully, we need to have corrent variable names, so for example that works:
interface MyObj {
x: number;
y: number:
}
let json_string = `{
"x": 5,
"y": 12
}`;
let test: MyObj = JSON.parse(json_string);
But if we change variable name in interface from "x" to lets say "xx" it becomes undefined after parsing. That creates seemingly unsolvable problem if we cant know all of the JSON object names, because I cant create an interface withh all of the planet names. Am I missing something? How would you parse a JSON I have posted?

Do you have any influence on the JSON itself? To me it seems that it is not the best way to use JSON. If I would try to design this, your JSON would look more like this:
{
"planets": [
{
"name": "Alderaan",
"available_items": [
{
"name": "Cinamone",
"available": 74,
"buy_price": 6,
"sell_price": 6
}, {
"name": "Dwimeryt",
"available": 42,
"buy_price": 12,
"sell_price": 11
}]
}]
}
This way you would always know the name of the fields and also their types. I do not think that this could be achieved easily with the current JSON format.

Related

JSON schema reference key value as the type of the field [duplicate]

I'm trying to validate json files which have an element that has a property which contains a value that should exist in another part of the json. I'm using jsonschema Draft 07.
This is a simple little example that shows the scenario I'm trying to validate in my data.
{
"objects": {
"object1": {
"colorKey": "orange"
}
},
"colors": {
"orange": {
"red": "FF",
"green": "AF",
"blue": "00"
}
}
}
How can I validate that the 'value' of colorKey (in this case 'orange') actually exists as a property of the 'colors' object? The data isn't stored in arrays, just defined properties.
For official JSON Schema...
You cannot check that a key in the data is the same as a value of the data.
You cannot extract the value of data from your JSON instance to use in your JSON Schema.
That being said, ajv, the most popular validator, implements some unofficial extensions. One of which is $data.
Example taken from: https://github.com/epoberezkin/ajv#data-reference
var ajv = new Ajv({$data: true});
var schema = {
"properties": {
"smaller": {
"type": "number",
"maximum": { "$data": "1/larger" }
},
"larger": { "type": "number" }
}
};
var validData = {
smaller: 5,
larger: 7
};
ajv.validate(schema, validData); // true
This would not work for anyone else using your schemas.

Add string literal into JSONPath output

Can I add a string literal to a JSONPath selector?
{ "items": [
{ "x": 1 },
{ "x": 2 },
{ "x": 3 },
{ "x": 4 }]
}
$.items[:].x gives...
[
1,
2,
3,
4
]
For example, can I make it return...
[
{ 1 },
{ 2 },
{ 3 },
{ 4 }
]
I want to generate some code that adds items to a dictionary.
As discussed in the comments, this cannot be done using JSONPath (alone) since a path query returns only valid JSON and the target format is not valid. In general, JSONPath is not the right tool here, a JSON transformation using a library like Jolt would be more appropriate; but again, similar to XSLT transformations, we can only create valid output. So, as you already have found out, you would need to use string functions to mingle the code as needed. For instance, a regex substitution could do:
const regex = /(\d+),?/gm;
const str = `[
1,
2,
3,
4
]`;
const subst = `{ $1 },`;
// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);
console.log('Substitution result: ', result);

Json object with nested objects, nested objects | mockable

I'm trying to create a test API in mockable.
What am I trying to create?
I'm trying to build an Json object with a Nested object which holds another nested object.
Example for use: store object => Store info => product list
What I expect to create
{
"Object": {
"id": 0,
"name": "Nova",
"nestedObject": {
{
"id": 1,
"name": "NestedNestedObject1",
},
{
"id": 2,
"name": "NestedNestedObject2",
},
}
Result I'm getting:
Error: Parse error on line 11:
...: { {
----------------------^
Expecting 'STRING', '}'
At NestedNestedObject2
How do I create a nested, nested object? If I'm correct mockable accepts pure Json
It depends on what you want to create and that depends on your API. The actual problem is that your JSON is not valid.
After your nestedObject there is just a { and that is wrong. In this case I assume you want to have an array of nestedObject (and perhaps also name should be nestedObjects) so fix would be (see the array []):
{
"Object": {
"id": 0,
"name": "Nova",
"nestedObject": [
{
"id": 1,
"name": "NestedNestedObject1"
},
{
"id": 2,
"name": "NestedNestedObject2"
}
]
}
}

Ruby: How to parse json to specific types

I have a JSON that I want to parse in Ruby. Ruby is completely new to me, but I have to work with it :-)
Here is my litte snippet, that should do the parsing:
response = File.read("app/helpers/example_announcement.json")
JSON.parse(response)
this works pretty fine. The only downside is, I do not know the properties at the point where I use it, it is not typesafe. So I created the objects for it
class Announcements
##announcements = Hash # a map key => value where key is string and value is type of Announcement
end
class Announcement
##name = ""
##status = ""
##rewards = Array
end
And this is how the json looks like
{
"announcements": {
"id1" : {
"name": "The Diamond Announcement",
"status": "published",
"reward": [
{
"id": "hardCurrency",
"amount": 100
}
]
},
"id2": {
"name": "The Normal Announcement",
"players": [],
"status": "published",
"reward": []
}
}
}
So I tried JSON parsing like this
response = File.read("app/helpers/example_announcement.json")
JSON.parse(response, Announcements)
But this is not how it works^^can anybody help me with this?

JSON deserialization with GSON error -- This is not a JSON Array

I know there have been a lot of questions on this topic already, but I'm stuck here and I'm sure it's something quite stupid.
I'm parsing a JSON Api that looks like this (renamed & simplified here):
{
"merchant": {
"name": "TestCo",
"id": 108
},
"category": [
{
"merchant_id": 108,
"category_name": "Baby Supplies",
"category_id": 57,
},
{
"merchant_id": 108,
"category_name": "Dining",
"category_id": 59,
}
]}
I have a wrapper class, defined as:
public class WrapperObject {
public MerchantObject merchant;
public List<CategoryObject> category;}
Both merchant & category are properly defined classes of their own. Then I try to deserialize like so:
collectionType = new TypeToken<List<WrapperObject>>() {}.getType();
List<WrapperObject> wrapperObject = new Gson().fromJson(response, collectionType);
This blows up, GSON reports back "This is not a JSON Array".
This worked perfectly right up until last week, when the API changed. The only difference in the JSON was that it used to look like this (note the extra wrapping array around the data):
[{
"merchant": {
"name": "TestCo",
"id": 108
},
"category": [
{
"merchant_id": 108,
"category_name": "Baby Supplies",
"category_id": 57,
},
{
"merchant_id": 108,
"category_name": "Dining",
"category_id": 59,
}
]}]
How do I adjust my code to parse the new JSON? NB, I have no control over the JSON. Thanks!
The square brackets around the old response denote an array (of one element in this case). It looks like the new API returns just a wrapper object, not an array of wrapper objects. Does this work?
wrapperType = new TypeToken<WrapperObject>() {}.getType();
WrapperObject wrapperObject = new Gson().fromJson(response, wrapperType);