I have a huge json file with 5500 records. The file display three levels as you see in the code and i want to extract all the records with a define level . How can i do that?
{
"Dictionary": {
"Words": [
{
"name": "fdfafd",
"level": "easy"
},
{
"name": "dfdaf",
"level": "medium"
},
{
"name": "ddsss",
"level": "difficult"
},
{
"name": "fdfafd",
"level": "easy"
},
{
"name": "dfdfadaf",
"level": "medium"
},
{
"name": "ddddsss",
"level": "difficult"
}
]
}
}
Its case of deep serialization. You need right object structure to accommodate it.
Such as following (add getters and setters and default constructor in case you overload constructor):
Class Dictionary{
List<Words> words;
Class Words {
String name;
String level;
}
}
While initialize serializer use something like :
jsonSerializer.include("words");
jsonSerializer.include("words.*");
Related
My project is about a shopping application build with Spring boot. When I get the shopping cart from the endpoint. It will return JSON like this
{
"shoppingCartCode": 2,
"productDetailList": [
{
"productDetailCode": 5,
"price": 21000.0,
"dateManufacture": "2021-09-23",
"quantity": 10,
"colorName": "Pink",
"warranty": 2,
"product": {
"prodCode": 2,
"prodName": "Z Flod 10",
"description": "Z Flod 10 Flippable then Break up",
"brand": {
"brandName": "Samsung",
"imageList": []
},
"shop": {
"shopCode": 5,
"shopName": "Montri Phone",
"shopDescription": "Strict security",
"type": "SELLER",
"imageList": []
}
},
"imageList": [
{
"imageName": "i-agree.png"
},
{
"imageName": "i-agree1.png"
},
{
"imageName": "i-agree2.png"
},
{
"imageName": "i-agree3.png"
}
]
}
]
}
I want to manipulate the imageList to like this
"imageList": ["i-agree.png","i-agree1.png","i-agree2.png","i-agree3.png"]
Is there any way to manipulate JSON before response?
or it might need POJO to wrap it up before response again?
You can achieve this with a custom serializer as follows:
public class ImageListConverter extends StdConverter<List<Image>, List<String>> {
#Override
public List<String> convert(List<Image> images) {
return images.stream().map(User::getImageName).collect(Collectors.toList());
}
}
Now you just need to annotate the imageList property:
public class ProductDetail {
#JsonSerialize(converter = ImageListConverter.class)
List<Image> imageList;
}
The other option would be changing List<Image> to List<String> and do the conversion when creating ProductDetail. It really depends on how you use ProductDetail elsewhere.
EDIT: TLDR there is currently no way to know material names on the fragment level.
I want to read the materials from fragments of a node and change their materials according to a map that uses the Revit material names as keys.
I have the following "Materials and Finishes" properties from a node in the model (retrieved via Viewer3D):
And I have the following THREE materials from the fragments of that node:
Is there a way to set the names of the THREE materials to match the model data (or use them at all)?
Ideally I would be able to match these THREE materials with the following materials extracted from this node:
The SVF file format (generated by the Model Derivative service and loaded by Forge Viewer) does not preserve material names unfortunately. The fragments are simply associated with a specific material based on its index in the list.
The "Materials and Finishes" data is basically just a property specific to the original file (in this case a Revit model), and it may not be available in other file formats.
EDIT: I tried looking into the Materials.json.gz file, and unfortunately the names are not included there, either:
{
"name": "LMVTK Simple Materials",
"version": "1.0",
"scene": {
"SceneUnit": 8215,
"YIsUp": 0
},
"materials": {
"0": {
"version": 2,
"userassets": ["0"],
"materials": {
"0": {
"tag": "",
"proteinType": "",
"definition": "SimplePhong",
"properties": {
"integers": {
"mode": 4
},
"booleans": {
"color_by_object": false,
"generic_is_metal": false,
"generic_backface_cull": true
},
"scalars": {
"generic_transparency": {
"units": "",
"values": [0]
}
},
"colors": {
"generic_diffuse": {
"values": [{
"r": 0,
"g": 1,
"b": 0,
"a": 1
}]
}
}
},
"transparent": false,
"textures": {
}
}
}
},
"1": {
"version": 2,
"userassets": ["0"],
"materials": {
"0": {
"tag": "",
"proteinType": "",
"definition": "SimplePhong",
"properties": {
"integers": {
"mode": 4
},
"booleans": {
"color_by_object": false,
"generic_is_metal": false,
"generic_backface_cull": true
},
"scalars": {
"generic_transparency": {
"units": "",
"values": [0]
}
},
"colors": {
"generic_diffuse": {
"values": [{
"r": 0.400000,
"g": 0.400000,
"b": 0.400000,
"a": 1
}]
}
}
},
"transparent": false,
"textures": {
}
}
}
}
...
}
I have Json data like below
{
"!type": "alarm",
"$": {
"12279": {
"!type": "alarm",
"title": "Default",
"$": {
"5955": {
"!type": "alarm",
"name": "Wake",
"day": "SUN",
"startTime": "06:00"
},
"29323": {
"!type": "alarm",
"name": "Away",
"day": "SUN",
"startTime": "08:00"
},
"2238": {
"!type": "alarm",
"name": "Home",
"day": "SUN",
"startTime": "18:00"
}
}
}
}
}
My fbs looks like this
namespace space.alarm;
table Atom{
!type:string;
name:string;
startDay:string;
startTime:string; }
table AtomShell{
key:string (required, key);
value: Atom; }
table Alarm{
!type:string;
title:string;
$:[AtomShell]; }
table AlarmShell{
key:string (required, key);
value:Alarm; }
table Weeklyalarm{
!type:string;
$:[AlarmShell]; } root_type Weeklyalarm;
Im trying to implement google flat buffers but I'm getting errors like
alarm.fbs:4:0: error: illegal character: !
alarm.fbs:23:0: error: illegal character: $ (i have removed ! from
!type and changed $ to dollar to test the working of flat buffers
but i can't change the dynamic ids )
Sample.json:25:0: error: unknown field: 12279
Now my question,
Is it possible to use dynamic ids in flat buffers, if possible how
shall i proceed?
Can is use special characters in ids, if possible how to do it?
Thanks in advance.
You can't have characters like ! and $ in field names. Just use type instead of !type, etc.
Not sure what you mean by dynamic ids. All field names (keys) have to be declared in the schema, so they can't be dynamic. You can still achieve similar results though, if you make your JSON look something like this:
{
"type": "alarm",
"data": [
{
id: "12279",
"type": "alarm",
"title": "Default",
"data": [
{
"id": "5955",
"type": "alarm",
"name": "Wake",
"day": "SUN",
"startTime": "06:00"
},
{
"id": "29323",
"type": "alarm",
"name": "Away",
"day": "SUN",
"startTime": "08:00"
},
{
"id": "2238",
"type": "alarm",
"name": "Home",
"day": "SUN",
"startTime": "18:00"
}
]
}
]
}
And then make the corresponding schema.
Note that I made the "dynamic" list into a vector, and moved the id into the object itself.
Other tip: string values that are not dynamic (like "alarm") will take up way less space if you make them into an enum instead.
I have JSON that looks like the below. I'm trying to use JSONPath to grab the __ content __ value where the SKU is "8A-OK9F-9LI8" AND the Component.Type == 'Principal'. Right now, I am playing around with this JSON Path Expression Tester.
This JSONPath expression grabs all of the component information I need:
$.Order..Fulfillment[?(#.SKU=='8A-OK9F-9LI8')]..Component
But filtering further such as $.Order..Fulfillment[?(#.SKU=='8A-OK9F-9LI8')]..Component[?(#.Type=='Principal')] grabs only one (I believe the Array one) of the two Component elements I need. I suspect this is because one is an Array and one is a single JSON element. Is it possible to grab this with one command or do I have to combine several commands (one for the Array and one for the single JSON element)? If so, how can I grab the other Component information that I am not currently getting with:
$.Order..Fulfillment[?(#.SKU=='8A-OK9F-9LI8')]..Component[?(#.Type=='Principal')]?
Again, my goal is to grab the "__ content__" value and filter by a specific SKU and where the Component.Type == 'Principal'. Something like:
$.Order..Fulfillment[?(#.SKU=='8A-OK9F-9LI8')]..Component[?(#.Type=='Principal')]..Amount..__content__
I'm expecting to get back ["8.49", "8.49"]
Here is the JSON I am testing with:
{
"SettlementData": {},
"Order": [
{
"OrderID": "XXX",
"Fulfillment": {
"Item": {
"SKU": "8A-OK9F-9LI8",
"Quantity": "1",
"ItemPrice": {
"Component": [
{
"Type": "Principal",
"Amount": {
"__content__": "8.49",
"currency": "USD"
}
},
{
"Type": "Tax",
"Amount": {
"__content__": "0.74",
"currency": "USD"
}
}
]
}
}
}
},
{
"OrderID": "XXX",
"Fulfillment": {
"Item": {
"SKU": "8A-OK9F-9LI8",
"Quantity": "1",
"ItemPrice": {
"Component": {
"Type": "Principal",
"Amount": {
"__content__": "8.49",
"currency": "USD"
}
}
}
}
}
}
]
}
I was able to solve this in two passes. In this example, #{sku} is a Ruby interpolated string that contains the SKU I am passing in:
$.Order..Fulfillment[?(#.SKU=='#{sku}')]..ItemPrice..[?(#.Type=='Principal')].Amount.__content__
$.Order..Fulfillment..Item[?(#.SKU=='#{sku}')]..ItemPrice..[?(#.Type=='Principal')].Amount.__content__
Using a Ruby gem "jsonpath", I was able to get the amounts I needed like this:
amount = JsonPath.on(settlement, "$.Order..Fulfillment[?(#.SKU=='#{sku}')]..ItemPrice..[?(#.Type=='Principal')].Amount.__content__")
.map(&:to_f).inject(:+)
amount2 = JsonPath.on(settlement, "$.Order..Fulfillment..Item[?(#.SKU=='#{sku}')]..ItemPrice..[?(#.Type=='Principal')].Amount.__content__")
.map(&:to_f).inject(:+)
I'm trying to use JsonBuilder with Groovy to dynamically generate JSON. I want to create a JSON block like:
{
"type": {
"__type": "urn",
"value": "myCustomValue1"
},
"urn": {
"__type": "urn",
"value": "myCustomValue2"
},
"date": {
"epoch": 1265662800000,
"str": "2010-02-08T21:00:00Z"
},
"metadata": [{
"ratings": [{
"rating": "NR",
"scheme": "eirin",
"_type": {
"__type": "urn",
"value": "myCustomValue3"
}
}],
"creators": [Jim, Bob, Joe]
}]
}
I've written:
def addUrn(parent, type, urnVal) {
parent."$type" {
__type "urn"
"value" urnVal
}
}
String getEpisode(String myCustomVal1, String myCustomVal2, String myCustomVal3) {
def builder = new groovy.json.JsonBuilder()
def root = builder {
addUrn(builder, "type", myCustomVal1)
addUrn(builder, "urn", "some:urn:$myCustomVal2")
"date" {
epoch 1265662800000
str "2010-02-08T21:00:00Z"
}
"metadata" ({
ratings ({
rating "G"
scheme "eirin"
addUrn(builder, "_type", "$myCustomVal3")
})
creators "Jim", "Bob", "Joe"
})
}
return root.toString();
}
But I've run into the following issues:
Whenever I call addUrn, nothing is returned in the string. Am I misunderstanding how to use methods in Groovy?
None of the values are encapsulated in double (or single) quotes in the returned string.
Anytime I use a {, I get a '_getEpisode_closure2_closure2#(insert hex)' in the returned value.
Is there something wrong with my syntax? Or can someone point me to some example/tutorial that uses methods and/or examples beyond simple values (e.g. nested values within arrays).
NOTE: This is a watered down example, but I tried to maintain the complexity around the areas that were giving me issues.
You have to use delegate in addUrn method instead of
passing the builder on which you are working.
It is because you are doing a toSting() or toPrettyString() on root instead of builder.
Solved if #2 is followed.
Sample:
def builder = new groovy.json.JsonBuilder()
def root = builder {
name "Devin"
data {
type "Test"
note "Dummy"
}
addUrn(delegate, "gender", "male")
addUrn(delegate, "zip", "43230")
}
def addUrn(parent, type, urnVal) {
parent."$type" {
__type "urn"
"value" urnVal
}
}
println builder.toPrettyString()
Output:-
{
"name": "Devin",
"data": {
"type": "Test",
"note": "Dummy"
},
"gender": {
"__type": "urn",
"value": "male"
},
"zip": {
"__type": "urn",
"value": "43230"
}
}