i have this task to parse json data to object, as in
{
"AAA" : {
"A1" : "a1 comment",
"A2" : "a2 comment"
},
"BBB" : {
"B1" : "b1 comment"
},
"CCC" : {
"C1" : "c1 comment",
"C2" : "c2 comment",
"C3" : "c3 comment"
"C4" : "c4 cooment"
},
"DDD" : {
"D1" : "d1 comment"
}
}
need to be converted to objects like ,
class Schema {
String tableName;
List<Column> colData;
And
class Column {
String columnName;
String columnComments;
Since i am a beginner to json, i took to the approach of first parsing things to xml and if it works proceed to parsing xml to object.
but i am having trouble parsing the json data.
however if i replace all the single quotes with double quotes and and '=>' with ':' and only consider AAA, i am able to parse with below code, but if i use the whole json data it throws error.
any help is deeply appreciated.
the code that i have so far is :
FileInputStream fis = new FileInputStream(new File("schema.sql"));
Transformer transformer = TransformerFactory.newInstance().newTransformer();
InputSource source = new InputSource(new StringReader(IOUtils.toString(fis, "UTF-8")));
DOMResult result = new DOMResult();
transformer.transform(new SAXSource(new JsonXmlReader("Table"), source), result);
Node n=result.getNode();
System.out.println(result.toString());
StringWriter writer = new StringWriter();
// Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(new DOMSource(n), new StreamResult(writer));
String xml = writer.toString();
System.out.println(xml);
which works for below data:
{
"AAA" : {
"A1" : "a1 comment",
"A2" : "a2 comment"
}
}
ofcourse i had to replace all ' with " and => with :
for the json data
{
"AAA" : {
"A1" : "a1 comment",
"A2" : "a2 comment"
},
"BBB" : {
"B1" : "b1 comment"
}
}
the error that i see is :
ERROR: 'Parsing error: HIERARCHY_REQUEST_ERR: An attempt was made to insert a node where it is not permitted. '
javax.xml.transform.TransformerException: net.javacrumbs.json2xml.JsonSaxAdapter$ParserException: Parsing error: HIERARCHY_REQUEST_ERR: An attempt was made to insert a node where it is not permitted.
at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(Unknown Source)
net.javacrumbs.json2xml.JsonSaxAdapter$ParserException: Parsing error: HIERARCHY_REQUEST_ERR: An attempt was made to insert a node where it is not permitted.
at net.javacrumbs.json2xml.JsonSaxAdapter.parse(JsonSaxAdapter.java:177)
at net.javacrumbs.json2xml.JsonXmlReader.parse(JsonXmlReader.java:152)
Related
I am totally new to groovy script and would like some help to solve this out. I have a JSON response I want to manipulate and get desired parameters back by avoiding duplication. The Json response does not have indexes like 0,1,2.. that I can iterate through.
Here is the response that I want to work with:
{
"AuthenticateV2" : {
"displayName" : "Verification of authentication",
"description" : "notification ",
"smsTemplate" : "authentication.v2.0_sms",
"emailHeaderTemplate" : "v2.0_header",
"emailBodyTemplate" : "html",
"parameters" : {
"displayName" : "USER_DISPLAY_NAME",
"actionTokenURL" : "VERIFICATION_LINK",
"customToken" : "VERIFICATION_CODE"
},
"supportedPlans" : [
"connectGo"
]
},
"PasswordRecovery" : {
"displayName" : "Verification of password recovery",
"description" : "notification",
"smsTemplate" : "recovery.v1.0_sms",
"emailHeaderTemplate" : "recovery.v1.0_header",
"emailBodyTemplate" : "recovery.v1.0_body_html",
"parameters" : {
"displayName" : "USER_DISPLAY_NAME",
"actionTokenURL" : "VERIFICATION_LINK",
"customToken" : "VERIFICATION_CODE",
"adminInitiated" : false,
"authnId" : "AUTHENTICATION_IDENTIFIER",
"authnType" : "EMAIL",
"user" : {
"displayName" : "USER_DISPLAY_NAME"
}
},
"supportedPlans" : [
"connectGo"
]
},
"PasswordReset" : {
"displayName" : "password reset",
"description" : "notification",
"smsTemplate" : "recovery.v1.0_sms",
"emailHeaderTemplate" : "recovery.v1.0_header",
"emailBodyTemplate" : "html",
"parameters" : {
"displayName" : "USER_DISPLAY_NAME",
"user" : {
"displayName" : "USER_DISPLAY_NAME"
}
}
The expected output that I want to have:
{
"displayName" : "USER_DISPLAY_NAME",
"actionTokenURL" : "VERIFICATION_LINK",
"customToken" : "VERIFICATION_CODE",
"customToken" : "VERIFICATION_CODE",
"adminInitiated" : false,
"authnId" : "AUTHENTICATION_IDENTIFIER",
"authnType" : "EMAIL"
}
I need to retrieve all fields under parameters tag and also want to avoid duplication
You should first get familiar with parsing and producing JSON in Groovy.
Then, assuming the provided response is a valid JSON (it's not - there are 2 closing curlies (}) missing at the end) to get all the parameters keys merged into one JSON we have to convert the JSON string into a Map object first using JsonSlurper:
def validJsonResponse = '<your valid JSON string>'
Map parsedResponse = new JsonSlurper().parseText(validJsonResponse) as Map
Now, when we have a parsedResponse map we can iterate over all the root items in the response and transform them into the desired form (which is all the unique parameters keys) using Map::collectEntries method:
Map uniqueParameters = parsedResponse.collectEntries { it.value['parameters'] }
Finally, we can convert the uniqueParameters result back into a pretty printed JSON string using JsonOuput:
println JsonOutput.prettyPrint(JsonOutput.toJson(uniqueParameters))
After applying all the above we'll get the output
{
"displayName": "USER_DISPLAY_NAME",
"actionTokenURL": "VERIFICATION_LINK",
"customToken": "VERIFICATION_CODE",
"adminInitiated": false,
"authnId": "AUTHENTICATION_IDENTIFIER",
"authnType": "EMAIL",
"user": {
"displayName": "USER_DISPLAY_NAME"
}
}
If you want to get rid of user entry from the final output just remove it from the resulting uniqueParameters map (uniqueParameters.remove('user')) before converting it back to JSON string.
I have the following terraform config:
resource "aws_dynamodb_table_item" "my_table" {
table_name = aws_dynamodb_table.my_table.name
hash_key = aws_dynamodb_table.my_table.hash_key
item = <<ITEM
{
"id": {"S": "nameAndCodes"},
"data": {"S": "[
{
"code": "03",
"displayName": "name1"
},
{
"code": "04",
"displayName": "name2"
}
]"}
}
ITEM
}
When the plan stage executes I receive the error:
Error: Invalid format of "item": Decoding failed: invalid character '\r' in string literal
The only way i can get this to work is to make the whole json a single line as follows:
"data": {"S": "[{\"code\": \"03\", \"displayName\": \"name1\"},{\"code\": \"04\", \"displayName\": \"name2\"}]"
This looks very ugly and difficult to manage.
Does anyone know how I can enter a multiline JSON inside a <<ITEM block?
To resolve that issue, You can use the jsonencode function to set the item value and put entire JSON object in there. Here is an example in Terraform from my project which creates a DynamoDB table and put an initial item.
resource "aws_dynamodb_table" "customer_table" {
name = "customer"
billing_mode = "PAY_PER_REQUEST"
hash_key = "customerId"
stream_enabled = false
attribute {
name = "customerId"
type = "S"
}
}
resource "aws_dynamodb_table_item" "customer_table_item" {
table_name = aws_dynamodb_table.customer_table.name
hash_key = aws_dynamodb_table.customer_table.hash_key
depends_on = [aws_dynamodb_table.customer_table]
item = jsonencode({
"customerId" : {
"S" : "1"
},
"firstName" : {
"S" : "John"
},
"lastName" : {
"S" : "Doe"
},
})
}
commands:
terrform init
terraform fmt
terraform plan
terraform apply
I am using the following code to read the CSV file and parse its data to JSON.
File inputFile = new File("in.csv");
File outputFile = new File("out.json");
CsvSchema csvSchema = CsvSchema.builder().setUseHeader(true).build();
CsvMapper csvMapper = new CsvMapper();
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
mapper.writerWithDefaultPrettyPrinter().writeValue(outputFile,
csvMapper.readerFor(Map.class).with(csvSchema).readValues(inputFile).readAll());
This is working fine and giving me output as follow,
[
{
"Nutrient" : "Calories",
"Amount" : " 289.00",
"Unit" : " kcal"
}, {
"Nutrient" : "Fat",
"Amount" : " 17.35",
"Unit" : " g"
}
]
But the required output is
{
{
"Nutrient" : "Calories",
"Amount" : " 289.00",
"Unit" : " kcal"
}, {
"Nutrient" : "Fat",
"Amount" : " 17.35",
"Unit" : " g"
}
}
Actually I need to read the JSONs files that I have converted from CSVs. Using the following code
String content = Files.readString(filePath);
JSONObject jsonObject1 = new JSONObject(content);
HashMap yourHashMap1 = new Gson().fromJson(jsonObject1.toString(), HashMap.class);
But while I am trying to do it gives me this error.
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.json.JSONException: A JSONObject text must begin with '{' at 1 [character 2 line 1]
Meanwhile json file should start with { instead of [ and similarly it should end on } instead ].
My goal is to remove this error.
I think the result you are seeing is correct and that is the way JSON is supposed to be. JSON is a key value based format.
The output which you have pasted just means it is an array of json objects
[
{
"Nutrient" : "Calories",
"Amount" : " 289.00",
"Unit" : " kcal"
}, {
"Nutrient" : "Fat",
"Amount" : " 17.35",
"Unit" : " g"
}
]
The below JSON actually makes no sense, as there are no keys to the object. Even if you try to parse this kind of JSON with Jackson, it will throw an error Exception in thread "main" com.fasterxml.jackson.core.JsonParseException: Unexpected character ('{' (code 123)): was expecting double-quote to start field name
at [Source: (String)"{ . You can try this out
{
{
"Nutrient" : "Calories",
"Amount" : " 289.00",
"Unit" : " kcal"
}, {
"Nutrient" : "Fat",
"Amount" : " 17.35",
"Unit" : " g"
}
}
The other option would be to consider each json object as a unique node with a distinct name like below, see the keyword set1 and set2
{
"set1": {
"Nutrient" : "Calories",
"Amount" : " 289.00",
"Unit" : " kcal"
},
"set2": {
"Nutrient" : "Fat",
"Amount" : " 17.35",
"Unit" : " g"
}
}
For some reason if you really want to have {} instead of [] then just make a string operation and replace 1st "[" with "{" and last "]" with "}
Edited the answer to match the edited question:
Now as we know your JSON is an array of JSON objects, you have to read it as JSONArray instead of JSONObject, also you can no more read it to a hashmap, it has to be a list, where each element in the list will be a JSONObject which has your data. Working code snippet is below
String content = Files.readString(filePath);
JSONArray jsonArray = new JSONArray(content);
List<LinkedTreeMap> yourList = new Gson().fromJson(jsonArray.toString(), ArrayList.class);
for(LinkedTreeMap l : yourList) {
System.out.println(l.get("Amount"));
System.out.println(l.get("Nutrient"));
System.out.println(l.get("Unit"));
}
I have a JSON object as below and I need to pass some of the object via a jQuery Attribute tag. I am getting a JSON parse error but I am not sure why.
"Walkers" : "true",
"Owners" :[
{
"Name":"Bob",
"Description":"Old",
"Pets": [
{"Name" : "Cuddles", "Age": "8"},
{"Name" : "Pounce", "Age": "3"}
]
},
{
"Name":"Mary",
"Description":"Older",
"Pets": [
{"Name" : "Red", "Age": "13"},
{"Name" : "Leaf", "Age": "1"}
]
}
]
In my razor page I am serialising the section of the JSON object I need.
#foreach (var people in myjson) {
<p>#people.Walkers</p> //true
<div id="mytarget" data-owners='#Json.Serialize(people.Owners)'> </div>
}
In jQuery:
var val = $("#mytarget").data('owners');
console.log("json " + val); // result: json [object Object],[object Object]
console.log("parsed " + JSON.parse(val)); // result: VM7:1 Uncaught SyntaxError: Unexpected token o in JSON at position 1 at JSON.parse (<anonymous>)
If I don't use JSON.Parse and just try and loop through the object in JQuery I just end up with '0' and '1'
var val = $("#mytarget").data('owners');
for (var obj in val) {
Console.log(obj);
}
Result '0' and '1'.
I have a JSON object as below and I need to pass some of the object via a jQuery Attribute tag. I am getting a JSON parse error
If you use console.log(val); to output the val to console tab, you would find you have gotten a json array, like below.
when I try to use obj.Name I get 'undefined'
To extract data of owner and pets from that array, you can refer to the following code snippet.
var val = $("#mytarget").data('owners');
//console.log("json " + val);
console.log(val);
$.each(val, function (index, owner) {
//owner object
console.log("Name: "+owner.name+"; Description: "+owner.description);
//pets of current owner
$.each(owner.pets, function (index, pet) {
console.log("Name: "+pet.name+"; Age: "+pet.age);
})
})
That's because you're passing an array of object instead of an object
so in your console you're getting something like this:
[
{
"Name":"Bob",
"Description":"Old",
"Pets": [
{"Name" : "Cuddles", "Age": "8"},
{"Name" : "Pounce", "Age": "3"}
]
},
{
"Name":"Mary",
"Description":"Older",
"Pets": [
{"Name" : "Red", "Age": "13"},
{"Name" : "Leaf", "Age": "1"}
]
}
]
You can't parse an array like a object will be return a error.
You can also use devtools to see how the data is coming, maybe it is coming in another format, here is the docs for more info https://developers.google.com/web/tools/chrome-devtools/inspect-styles/
The error is in the for bucle the correct syntax is:
var val = $("#mytarget").data('owners');
for (i = 0; i < val.length; i++) {
console.log(val[i])
}
here is the docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration
Or you can use map: https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Array/map
var val = $("#mytarget").data('owners');
val.map(item => {
console.log(item)
})
I'm trying to deserialize a JSON object that is held in an Array. I'm using SwiftyJSON but the program is not behaving as I expected.
This is the array:
var GamesList = [JSON]();
The array holds my 2 JSON objects:
{
"game_type" : "TRADITIONAL",
"game_player_winner" : "",
"game_state" : "STARTED",
"self_left" : "2",
"self_right" : "1",
"self_name" : "test2",
"opponent_right" : "1",
"opponent_name" : "test1",
"game_guid" : "153fac87-bfc4-367f-41fa-944753dc32c8",
"game_idle_time" : 755858,
"opponent_left" : "3"
}, {
"game_type" : "TRADITIONAL",
"game_player_winner" : "",
"game_state" : "STARTED",
"self_left" : "2",
"self_right" : "1",
"self_name" : "test2",
"opponent_right" : "1",
"opponent_name" : "johannesswart",
"game_guid" : "153fac87-bfc4-367f-41fa-944753dc32c9",
"game_idle_time" : 755858,
"opponent_left" : "3"
}]hier is je gamestate: Optional({
"game_type" : "TRADITIONAL",
"game_player_winner" : "",
"game_state" : "STARTED",
"self_left" : "2",
"self_right" : "1",
"self_name" : "test2",
"opponent_right" : "1",
"opponent_name" : "testuser",
"game_guid" : "153fac87-bfc4-367f-41fa-944753dc32c9",
"game_idle_time" : 755858,
"opponent_left" : "3"
}
I create a new JSON object and fill it with a value of object 1 from the Array:
var gameState : JSON?;
self.gameState = GamesList[1];
When I print the entire self.gameState object to the console all is well and it looks like what I expected. However when I want to just use 1 value of this JSON object I can't seem to get it to work.
I tried with:
self.gameState["game_type"].string;
And:
var foo = JSON(self.gameState);
But this is both not compiling. What am I doing wrong?
I can see where this can be frustrating, but this is actually a pretty simple fix.
I had your same problem a while back when doing work with AlamoFire.
I can see why it's not compiling though, you are trying to retrieve a key out of an Array like:
self.gameState["game_type"]
but the Array type doesn't have key:value pairs, simple it is accessed via indexes:
self.gameState[1]
Step 1
So instead of an array, get your JSON into a dictionary. After that, follow these steps:
Make sure that your JSON data is being stored in a dictionary, like:
let jsonData: [String:String] = //your JSON
(use the var keyboard if you will be manipulating data in jsonData.
Step 2
After your JSON data is stored in a dictionary, simply do:
let gameState = jsonData["game_type"]!
You should not have a problem after that.
I hope I was able to shed some light, please comment if anything was unclear.