Does anybody know the best way to merge 2 JSON files? I am looking to move the 'awardClaimForms' from file 1 to file 2 while keeping the same 'number'. Would consider manual work if it was a few but I'm dealing with just over 1k entries. Any direction or help would be appreciated!
File 1 contains:
{
"Notices": [
{
"awardClaimForms": "form-21",
"number": "2015-031"
},
{
"awardClaimForms": "form22",
"number": "2015-030"
},
]
}
File 2 contains:
{
"Notices": [
{
"number": "2015-031",
"link": "http://www.yahoo.com",
"title": "myother sample title",
"awardClaimDueDate": "March 01, 2013",
"datePosted": "12/01/2012"
},
{
"number": "2015-030",
"link": "http://www.google.com",
"title": "my sample title",
"awardClaimDueDate": "March 01, 2013",
"datePosted": "12/01/2012"
},
]
}
Desired Outcome:
{
"Notices": [
{
"number": "2015-031",
"link": "http://www.yahoo.com",
"title": "myother sample title",
"awardClaimDueDate": "March 01, 2013",
"awardClaimForms": "form-21",
"datePosted": "12/01/2012"
},
{
"number": "2015-030",
"link": "http://www.google.com",
"title": "my sample title",
"awardClaimDueDate": "March 01, 2013",
"awardClaimForms": "form-22",
"datePosted": "12/01/2012"
},
]
}
import org.apache.commons.io.IOUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class JsonMerge {
public static void main(String[] args) throws IOException, JSONException {
// Read the json from the files
FileInputStream fileOne = new FileInputStream(new File("D:\\jsonOne.json"));
FileInputStream fileTwo = new FileInputStream(new File("D:\\jsonTwo.json"));
String stringOne = null, stringTwo = null;
try {
stringOne = IOUtils.toString(fileOne);
stringTwo = IOUtils.toString(fileTwo);
} finally {
fileOne.close();
fileTwo.close();
}
// Convert them into json objects
JSONObject jsonOne = new JSONObject(stringOne);
JSONObject jsonTwo = new JSONObject(stringTwo);
// Extract the arrays from the Notices Array
JSONArray jsonOneNoticesArray = jsonOne.getJSONArray("Notices");
JSONArray jsonTwoNoticesArray = jsonTwo.getJSONArray("Notices");
JSONObject mergedJsonArray = new JSONObject();
// Iterate and compare the required condition
for (int i = 0; i < jsonOneNoticesArray.length(); i++) {
for (int j = 0; j < jsonTwoNoticesArray.length(); j++) {
JSONObject mergedJson = new JSONObject();
if (jsonOneNoticesArray.getJSONObject(i).getString("number").equals(jsonTwoNoticesArray.getJSONObject(j).getString("number"))) {
mergedJson.accumulate("number", jsonOneNoticesArray.getJSONObject(i).getString("number"));
mergedJson.accumulate("link", jsonOneNoticesArray.getJSONObject(i).getString("link"));
mergedJson.accumulate("title", jsonOneNoticesArray.getJSONObject(i).getString("title"));
mergedJson.accumulate("awardClaimDueDate", jsonOneNoticesArray.getJSONObject(i).getString("awardClaimDueDate"));
mergedJson.accumulate("datePosted", jsonOneNoticesArray.getJSONObject(i).getString("datePosted"));
mergedJson.accumulate("awardClaimForms", jsonTwoNoticesArray.getJSONObject(j).getString("awardClaimForms"));
mergedJsonArray.append("Notices", mergedJson);
break;
}
}
}
System.out.println("Done merging.. " + mergedJsonArray);
}
}
Adding the below line (instead of System.out.println line) could write the output to the file
FileUtils.write(new File("D:\\mergedJson.json"), mergedJsonArray.toString());
and here is the output of the mergedJsonArray from the above code.
Related
I am trying to find the best way to compare 2 JSON Array objects using Groovy script.
JSON Obj1 =
{
"PO":
[
{
"OrderNumber": "12345",
"Location": "US",
}
{
"OrderNumber": "11223",
"Location": "US",
}
]
}
JSON Obj2 = {
"ResultPO":
[
{
"OrderNumber": "12345_00001",
"Location": "US",
"Customer": "ABC"
}
{
"OrderNumber": "98765_00002",
"Location": "US",
"Customer": "XYZ"
}
]
}
I need to return the JSON Output as below after finding the obj1 value in obj2 where OrderNumber is key identifier.
{
"ResultPO":
[
{
"OrderNumber": "12345_00001",
"Location": "US",
"Customer": "ABC"
}
]
}
Below is the sample code I have tried using JsonSlurper and findall but not able to get desired outcome.
def builder
def filterJson
filterJson = Obj2.findAll(){ it.OrderNumber.substring(0,4) == Obj1.OrderNumber.text()}
builder = new JsonBuilder(filterJson)
Try this one:
class OrderFilterSpec extends Specification {
def str1 = """{"PO":[
{"OrderNumber": "12345","Location": "US"},
{"OrderNumber": "11223","Location": "US"}
]}"""
def str2 = """{"ResultPO":[
{"OrderNumber": "12345_00001","Location": "US","Customer": "ABC"},
{"OrderNumber": "98765_00002","Location": "US","Customer": "XYZ"}
]}"""
def slurper = new JsonSlurper()
def buildResult(String first, String second) {
def (parsed1, parsed2) = [slurper.parseText(first), slurper.parseText(second)]
def filteredOrders = parsed2.ResultPO.findAll {
it.OrderNumber[0..4] in parsed1.PO.collect { it.OrderNumber }
}
return [ResultPO: filteredOrders]
}
def 'test order filtering'() {
expect:
buildResult(str1, str2) == [ResultPO: [[OrderNumber: '12345_00001', Location: 'US', Customer: 'ABC']]]
}
}
Whenever I try to execute below script I keep getting error, saying unexpected character (g).
Basically I want to be able to parse the json response and be able to get the upstream job name from it.
Script:
#Grapes([
#Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.7.1'),
#Grab(group='commons-collections', module='commons-collections', version='3.2.1'),
#Grab(group='org.jsoup', module='jsoup', version='1.10.2'),
#Grab(group='org.json', module='json', version='20190722'),
#Grab(group='com.googlecode.json-simple', module='json-simple', version='1.1.1')
])
import static groovyx.net.http.ContentType.*
import groovyx.net.http.HttpResponseException
import groovyx.net.http.RESTClient
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
import java.net.*
import java.util.*
import org.json.simple.*
import org.json.simple.parser.JSONParser;
def getRestClient(){
String jenkinsUrl="http://somedomainname:8080"
def restClient = new RESTClient(jenkinsUrl)
return restClient
}
def getJobsInfo(String jobname,RESTClient restClient){
def requrl= '/job/'+jobname+'/lastBuild/api/json/?pretty=true'
def response = restClient.get( path : requrl)
return response
}
def writeToPropertyFile(){
def jsonResponseObject = getJobsInfo("sampleJobName",getRestClient())
println "\n\n\n\n\n Json String :---- "+ jsonResponseObject.toString()
JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject) jsonParser.parse(jsonResponseObject.toString());
JSONArray upstreamJobInfoArray = jsonObject.getJSONArray("causes");
for (int i = 0; i < upstreamJobInfoArray.length(); i++) {
JSONObject jobCauses = upstreamJobInfoArray.getJSONObject(i);
String upstreamProjectName = jobCauses.getString("upstreamProject");
println upstreamProjectName
}
}
writeToPropertyFile()
Error :
Json String :---- groovyx.net.http.HttpResponseDecorator#6b063470
Caught: Unexpected character (g) at position 0.
Unexpected character (g) at position 0.
at org.json.simple.parser.Yylex.yylex(Yylex.java:610)
at org.json.simple.parser.JSONParser.nextToken(JSONParser.java:269)
at org.json.simple.parser.JSONParser.parse(JSONParser.java:118)
at org.json.simple.parser.JSONParser.parse(JSONParser.java:81)
at org.json.simple.parser.JSONParser.parse(JSONParser.java:75)
at org.json.simple.parser.JSONParser$parse.call(Unknown Source)
at getUpstreamJob.writeToPropertyFile(getUpstreamJob.groovy:39)
at getUpstreamJob.run(getUpstreamJob.groovy:50)
EDIT 1 : START
JSON response that I am trying to parse :
{
"_class": "hudson.model.FreeStyleBuild",
"actions": [
{
"_class": "hudson.model.CauseAction",
"causes": [
{
"_class": "hudson.model.Cause$UpstreamCause",
"shortDescription": "Started by upstream project \"sampleJobName\" build number 712",
"upstreamBuild": 712,
"upstreamProject": "sampleJobName",
"upstreamUrl": "job/sampleJobName/"
},
{
"_class": "hudson.model.Cause$UserIdCause",
"shortDescription": "Started by user Malick, Asif",
"userId": "asifma00",
"userName": "Malick, Asif"
},
{
"_class": "com.sonyericsson.rebuild.RebuildCause",
"shortDescription": "Rebuilds build #300",
"upstreamBuild": 300,
"upstreamProject": "sampleJobName",
"upstreamUrl": "view/ABCProjectView/job/sampleJobName/"
}
]
},
{
"_class": "hudson.model.ParametersAction",
"parameters": [
{
"_class": "hudson.model.StringParameterValue",
"name": "SNAPSHOTNAME",
"value": "ABCDE_12121.2000-2121212121212"
},
{
"_class": "hudson.model.StringParameterValue",
"name": "BUILD_LABEL",
"value": "ABCDE_12121.2000"
}
]
},
{},
{},
{},
{},
{
"_class": "hudson.plugins.parameterizedtrigger.BuildInfoExporterAction"
},
{},
{},
{},
{}
],
"artifacts": [],
"building": false,
"description": null,
"displayName": "#301",
"duration": 1199238,
"estimatedDuration": 1194905,
"executor": null,
"fullDisplayName": "sampleJobName #301",
"id": "301",
"keepLog": false,
"number": 301,
"queueId": 189076,
"result": "SUCCESS",
"timestamp": 1583500786857,
"url": "http://somedomainname:8080/job/sampleJobName/301/",
"builtOn": "Server12345",
"changeSet": {
"_class": "hudson.scm.EmptyChangeLogSet",
"items": [],
"kind": null
},
"culprits": []
}
EDIT 1 : END
I have tried looking at several Stack Overflow issues, but still haven't been able to resolve it.
Please guide.
It's because you're not getting the actual JSON string, you're getting the toString() output on a groovyx.net.http.HttpResponseDecorator class.
You can see it printing it out here (it's easy to miss though... I missed it the first look 🙂):
Json String :---- groovyx.net.http.HttpResponseDecorator#6b063470
I think you need to call jsonResponseObject.data to get the parsed data, and it might even return you a Map parsed form the JSON (so you can get rid of all your JSONObject code). Test it by changing to:
def data = jsonResponseObject.data
println "\n\n\n\n\n Json ${data.getClass().name} :---- $data" jsonResponseObject.toString()
If it is a java.util.Map, you can simplify your second part from:
JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject) jsonParser.parse(jsonResponseObject.toString());
JSONArray upstreamJobInfoArray = jsonObject.getJSONArray("causes");
for (int i = 0; i < upstreamJobInfoArray.length(); i++) {
JSONObject jobCauses = upstreamJobInfoArray.getJSONObject(i);
String upstreamProjectName = jobCauses.getString("upstreamProject");
println upstreamProjectName
}
To (using data from above):
data.actions.causes.upstreamProject.flatten().each { println it }
I am trying to get a value from a JSON file, however it is a complex JSON file and i'm not sure how to go about it.
The value is situated inside an object, that is inside another object, which inside another object.
The values I want to retrieve from the JSON file is "value" and "unit" situated inside the object "metric". I have been able to successfully retrieve the "name" value.
The JSON file:
{
"ingredients": [
{
"name": "breakfast sausage",
"image": "breakfast-sausage-links.jpg",
"amount": {
"metric": {
"value": 226.796,
"unit": "g"
},
"us": {
"value": 8,
"unit": "ounces"
}
}
},
I will also include the method that I parse the JSON from:
private void jsonParse(){
String url = "https://api.spoonacular.com/recipes/"+ rMealId + "/ingredientWidget.json?&apiKey=da7dd16a704f4552b70a96c1e9641b08";
RequestQueue requestQueue = Volley.newRequestQueue(this);
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("ingredients");
for(int i = 0; i < jsonArray.length(); i++){
JSONObject ingredients = jsonArray.getJSONObject(i);
String iName = ingredients.getString("name");
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
Log.e("Volley", error.toString());
}
});
requestQueue.add(request);
}
Just focusing on your json string, try this:
let ings =
{
"ingredients": [
{
"name": "breakfast sausage",
"image": "breakfast-sausage-links.jpg",
"amount": {
"metric": {
"value": 226.796,
"unit": "g"
},
"us": {
"value": 8,
"unit": "ounces"
}
}
}
]
}
let jp = require('jsonpath');
let eat = jp.query(ings, '$..metric.*');
console.log(eat);
output:
[ 226.796, 'g' ]
I have this JSON Builder Groovy code:
import groovy.json.JsonBuilder
import groovy.json.JsonOutput
import groovy.json.StreamingJsonBuilder
class JSONTest {
public static main(args) {
StringWriter writer = new StringWriter()
StreamingJsonBuilder builder = new StreamingJsonBuilder(writer)
builder.requests {
name 'HSV Maloo'
make 'Holden'
year 2006
country 'Australia'
}
String json = JsonOutput.prettyPrint(writer.toString())
println json
}
}
It produces output like this:
{
"requests": {
"name": "HSV Maloo",
"make": "Holden",
"year": 2006,
"country": "Australia"
}
}
But I want to make the output like this with the requests value as an array element:
{
"requests": [{
"name": "HSV Maloo",
"make": "Holden",
"year": 2006,
"country": "Australia"
}]
}
How I can change the output?
You can do this by using the form of the StreamingJsonBuilder DSL that allows you to pass an element name, a collection, and a closure to iterate over the collection with.
def requests = [
[name: 'HSV Maloo', make: 'Holden', year: 2006, country: 'Australia']
]
StringWriter writer = new StringWriter()
StreamingJsonBuilder builder = new StreamingJsonBuilder(writer)
builder.requests requests, { request ->
name request.name
make request.make
year request.year
country request.country
}
String json = JsonOutput.prettyPrint(writer.toString())
println json
Which will produce:
{
"requests": [
{
"name": "HSV Maloo",
"make": "Holden",
"year": 2006,
"country": "Australia"
}
]
}
I need to be able to loop through each "item" from my JSON result. The JSON response looks like this. I would like to be able to access each specific id.
{
"prop1": {
"date": "2017-03-04 3:57:38 PM",
"item": [
{
"id": "37705",
"date": "2016-04-03",
"time": "1:30PM"
},
"location": "Location 1"
},
{
"id": "2000",
"date": "2016-05-03",
"time": "2:30PM"
},
"location": "Location 2"
},
]
}
}
This is what i have but i am getting "Cannot access Children"
using (WebResponse response = await request.GetResponseAsync())
{
using (StreamReader stream = new StreamReader(response.GetResponseStream()))
{
var serializer = new JsonSerializer();
using (var jsonTextReader = new JsonTextReader(stream))
{
dynamic obj = serializer.Deserialize(jsonTextReader);
foreach (var item in obj)
{
foreach (var item2 in item["item"].Children())
{
Console.WriteLine(item2.id);
}
}
}
}
}