Map one JSON schema to a different JSON schema - json

I have a bunch of JSON files, thousands of different schemas. Using GenSON (the Python JSON schema generator), I managed to create schema files for each of the input files. Now, what I'd like to do is standardize all these different files to one defined schema. Here's an example:
Input
{
"name": "Bob Odenkirk",
"title": "Software Engineer",
"location": {
"locality": "San Francisco",
"region": "CA",
"country": "United States"
},
"age": 62,
"status": "Active"
}
Output
{
"names": ["Bob Odenkirk"],
"occupations": ["Software Engineer"],
"locations": ["San Francisco, CA"]
}
Essentially, I am looking for a language agnostic method (i.e., I don't care what programming language is used) of defining how an input JSON file should be parsed to an output JSON file.

The url https://github.com/bazaarvoice/jolt#jolt
says that Jolt may be what you're looking for.
Jolt
JSON to JSON transformation library written in Java where the "specification" for the transform is itself a JSON document.
Useful For
Transforming JSON data from ElasticSearch, MongoDb, Cassandra, etc before sending it off to the world
Extracting data from a large JSON documents for your own consumption

Jolt Spec
[
// First build the "city, state" string for location
{
"operation": "modify-default-beta",
"spec": {
"location": {
"locConcat": "=concat(#(1,locality),', ',#(1,region))"
}
}
},
// Then map the fields as needed to positions in an output json
{
"operation": "shift",
"spec": {
"name": "name[0]",
"title": "occupations[0]",
"location": {
"locConcat": "locations[0]"
}
}
}
]

I am not sure is your expecting like below. Long time back I have created flat object and output format object. It will return output format object with data filled.
var input = {
"name": "Bob Odenkirk",
"title": "Software Engineer",
"location": {
"locality": "San Francisco",
"region": "CA",
"country": "United States"
},
"age": 62,
"status": "Active"
};
var outputFormat = {
"name": "name",
"occupations": "title",
"locations": "location.locality, location.region"
};
var flatInput = {};
function generateFlatInput(input, parent){
for (var prop in input) {
if(input.hasOwnProperty(prop) && typeof input[prop] === 'object')
flatInput = generateFlatInput(input[prop], parent + prop + '.');
else
flatInput[parent + prop] = input[prop];
}
return flatInput;
}
function generateOutput(input, outputFormat, delimiter){
input = generateFlatInput(input, '');
for (var prop in outputFormat) {
var fields = outputFormat[prop].split(delimiter);
var fieldValue = [];
for(i = 0; i < fields.length; i++){
if(!input.hasOwnProperty(fields[i].trim())) continue;
fieldValue.push(input[fields[i].trim()]);
}
outputFormat[prop] = fieldValue.join(delimiter);
}
return outputFormat;
}
console.log(generateOutput(input, outputFormat, ', '));
https://jsfiddle.net/u2yyuguk/1/

I think the best, fastest, easiest way to parse many JSON files together is using python.
I was doing something similar to your project and ran into the same problem.
I found this site which teaches how to use python to actually parse JSON files together. Turns out there is a library on python called json(use pip to download json dependencies) which enables JSON file processing. If you already have a python editor, This method would be easier and faster then using Jolt
Check This website for more info: https://code.tutsplus.com/tutorials/how-to-work-with-json-data-using-python--cms-25758.
You can also use JS, which is again faster than Jolt. this is the website: https://learn.microsoft.com/en-us/scripting/javascript/reference/json-parse-function-javascript . It is very easy as you can use JSON.parse() function

Related

get by id from local json http

I have fake users.json file and I can http.get to list the array of json.
Since I want to get the particular user by id and haven't stored the data in the database, instead just use the fake json data.
[
{
"id": "cb55524d-1454-4b12-92a8-0437e8e6ede7",
"name": "john",
"age": "25",
"country": "germany"
},
{
"id": "ab55524d-1454-4b12-92a8-0437e8e6ede8",
"name": "tom",
"age": "28",
"country": "canada"
}
]
I can do this stuff if the data is stored in the database, but not sure how to proceed with the fake json data.
Any help is appreciated.
Thanks
If you need the json as raw data, for just fake data, You can simply require it and use it as object..
const JsonObj = require('path/to/file.json')
console.log(JsonObj[0].id) // <-- cb55524d-1454-4b12-92a8-0437e8e6ede7
Plus, if you need more dynamic solution, there is a good JSON-server you can easily use for testing and so: check this git repo
var _ = require('underscore');
var dummyJson = [
{
"id": "cb55524d-1454-4b12-92a8-0437e8e6ede7",
"name": "john",
"age": "25",
"country": "germany"
},
{
"id": "ab55524d-1454-4b12-92a8-0437e8e6ede8",
"name": "tom",
"age": "28",
"country": "canada"
}
]
var requiredID = "cb55524d-1454-4b12-92a8-0437e8e6ede7";
var reuiredObject = _.find(dummyJson, function (d) {
return d.id === requiredID;
})
Get JSON object using JSON.parse('users.json') and store it in a variable users.
Loop through array of users using for .. in and using if condition on id update the object if required.
Stringify the updated users object using JSON.stringify(users); and write this string to users.json file using fs.write() module in NodeJS so you will have updated objects in your json file.

Microsoft.Graph Unable to deserialize the response

I am quite new to programming and especially Microsoft.Graph
I am having problems handling the response to:
https://graph.microsoft.com/v1.0/me/drive/root/children
the response looks like this (just much longer):
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('xyz%40hotmail.com')/drive/root/children",
"value": [
{
"createdBy": {
"user": {
"displayName": "xyz",
"id": "cf58e4781082"
}
},
"createdDateTime": "2009-01-08T08:52:07.063Z",
"cTag": "adDpFREJDR4RTQMTgxMDgyITEyOC42MzYxODM0MTU0Mjc3MDAwMDA",
"eTag": "aRURCQ0Y1OEU0A4MiExMjguMA",
"id": "EDBCF58E471082!128",
"lastModifiedBy": {
"user": {
"displayName": "xyz",
"id": "edbcf58e48082"
}
}, ............. etc...
The response that I received is correct, in JSON format (I believe ><), but I cannot figure out how to parse it into an array containing the folders name.
Please help!
Have considered using the Microsoft Graph client library? It will deserialize the JSON. Your call will look like this:
// Return all children files and folders off the drive root.
var driveItems = await graphClient.Me.Drive
.Root
.Children
.Request()
.GetAsync();
foreach (var item in driveItems)
{
// Get your item information
}
Here's some samples to help you get started:
https://github.com/microsoftgraph?utf8=%E2%9C%93&q=csharp
You can use the JavaScriptSerializer to do this. Assuming
//json contains the JSON Response
var jsonOutput = new System.Web.Script.Serialization.JavaScriptSerializer();
jsonOutput.DeserializeObject(json);
This has been discussed earlier. See this thread: Easiest way to parse JSON response
Refer this link for JavaScriptSerializer: https://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer(v=vs.110).aspx

Removing excess comma on JSON Object

Currently been working on eliminating the excess "," comma on the json object I have below.
{"rules": {
"1000": {
"action": "2",
"category": "skype",
"entity": "Private",
"id": "1000",
},
"1200": {
"action": "2",
"category": "http",
"entity": "Public",
"id": "1200",
},
"100": {
"action": "2",
"category": "ftp",
"entity": "Public",
"id": "100",
},
"0": {
"entity": "Private",
"category": "alcohol, tobacco",
"action": "1",
"id": "low",
},
"3000": {
} }}
Maybe you have some insights on what's the cleanest way to eliminate it using AngularJS.
The data was parsed from this code snippet.
var request = {
url: 'sample/uri',
method: "GET",
transformResponse: specialTransform
};
var response = $q.defer( );
$http( request ).success( function( THIS DATA -> data, status ) {
eval
var fixTrailingCommas = function (jsonString) {
var jsonObj;
eval('jsonObj = ' + jsonString);
return JSON.stringify(jsonObj);
};
fixTrailingCommas('{"rules": { "1000": { "action": "2", "category": "skype", "entity": "Private", "id": "1000" , } } }');
Please use eval here only if you completely trust incoming json, and also be aware of other eval evils as described on MDN and its note on JSON parsing
Note that since JSON syntax is limited compared to JavaScript syntax, many valid JavaScript literals will not parse as JSON. For example, trailing commas are not allowed in JSON, and property names (keys) in object literals must be enclosed in quotes. Be sure to use a JSON serializer to generate strings that will be later parsed as JSON.
You may also choose to rely on implementation of JSON2 by Douglas Crockford which uses eval internally
On current browsers, this file does nothing,
preferring the built-in JSON object. There is no reason to use this file unless
fate compels you to support IE8, which is something that no one should ever
have to do again.
But because we really need to use this library, we have to make few code modifications, e.g. simply comment out JSON type check, which will then override native browser object (or we may also introduce new JSON2 global variable)
//if (typeof JSON !== 'object') {
JSON = {};
//}
P.S. Other parsing fuctions json_parse.js and json_parse_state.js, which don't use eval, throw a syntax error
Angular part
var config = {
transformResponse: function (data, headers) {
if(headers("content-type") === "application/json" && angular.isString(data)) {
try {
data = JSON.parse(data);
} catch (e) {
// if parsing error, try another parser
// or just fix commas, if you know for sure that the problem is in commas
data = JSON2.parse(data);
}
return data;
} else {
return data;
}
}
};
$http.get("rules.json", config).success(function (data) {
$scope.rules = data;
});
So as you said, the JSON is wrongly generated on the server you are taking it from, can you change the way it is generated there? (Follow this: Can you use a trailing comma in a JSON object?)
In case you are unable to do so, you need to use something like mentioned here:
Can json.loads ignore trailing commas?
library to repair a JSON object, like: https://www.npmjs.com/package/jsonrepair
(try some online fix tool here: http://www.javascriptformat.com/)
or some regexp magic

writing to previously existing json file(with array of objects and each object with an array member) using qt 5.3

I am using QT 5.3. I have read various materials present online describing how to write json file,but no content describes it systematically and stepwise.
It would be really helpful if someone can explain the stepwise process of writing a json file in simple language since i am new to qt.
In my case i have a json file that already exists "LOM.json" with some content.How do i add new data to this.
{
"LOM": [
{
"LOM ID": 1,
"Source": "Open Internet",
"Content": "Complete Reference Java.pdf",
"Difficulty Level": "Hard",
"Type": "Text",
"Length": "Long",
"Topic-Proficiency": [
{
"Topic": "Programming",
"Proficiency": "E2"
},
{
"Topic": "Java",
"Proficiency": "E3"
}
]
},
{
"LOM ID": 2,
"Source": "Open Internet",
"Content": "www.LatexTutorial.com",
"Difficulty Level": "Medium",
"Type": "WebCourse",
"Length": "Medium",
"Topic-Proficiency": [
{
"Topic": "Latex",
"Proficiency": "E2"
}
]
}
]
}
Thanks.
You can't directly insert data into the middle of the document. You would need to read the document and write it out again. Let's look at how we'd go about this.
Assuming the current JSON you posted is in memory as a QByteArray, you create a QJsonDocument:-
QJsonDocument doc = QJsonDocument::fromJson(data); // where data is the current JSON
If we want to add another LOM object to the array. We get the first object, which is the array:-
QJsonObject rootObj = doc.object();
QJsonValue lomObj = rootObj.value("LOM");
if(!lomObj.isArray())
{
// array expected - handle error
}
QJsonArray lomArray = lomObj.toArray();
Now we have the array, we can create a new object
QJsonObj newObject;
newObject["LOM ID"] = 3;
newObject["Source"] = "Open Internet"
newObject["Content"] = "Some other content"
//etc...
And add this to the array
lomArray.push_back(newObject);
Finally, you can create a new document and get a byte array of the data to write to the file
QJsonDocument newDoc(obj);
QByteArray finalData = newDoc.toJson();
I finally got it done.
Actually the mistake was that while declaring the QJsonObject and QjsonArray,i was declaring them as pointer type that's why it was not allowing to insert qjsonobject to qjsonarray.
As far as writing to already existing json file is concerned,firstly the file is to be opened and content is to be read in qjsonarray or object.Next the changes to be done are appended to the read data(in qjson object or qjsonarray) and finally the new value is inserted to the read document by removing the previous one.
Thanks #merlin069 and this post -Qt modifying a JSON file.

Simplify Couchdb JSON response

I'm storing location data in Couchdb, and am looking for a way to get an array of just the values, instead of key: value for every record. For example:
The current response
{"total rows": 250, "offset": 0, "rows":[
{"id": "ec5de6de2cf7bcac9a2a2a76de5738e4", "key": "user1", "value": {"city": "San Francisco", "address":"1001 Bayhill Dr"},
{"id": "ec5de6de2cf7bcac9a2a2a76de573ae4","key": "user1", "value": {"city": "Palo Alto", "address":"583 Waverley St"}
... (etc).
]}
I only really need:
[{"city": "San Francisco", "address":"1001 Bayhill Dr"},
{"city": "Palo Alto", "address":"583 Waverley St"},
...]
The reason for all this is to minimize the amount of bandwidth that a JSON response consumes.
I can't seem to find a way to transform the view into a simple array. Any suggestions?
Thanks.
You can use _show and _list functions, they take either a document or a view (respectively) and can send back a transformed response in whatever format you need. (in this case, JSON)
Update: I ran a simple test with the data you provided here on my own CouchDB. Here's the list function I ended up writing. Customize it to fit your needs. :)
function (head, req) {
// specify that we're providing a JSON response
provides('json', function() {
// create an array for our result set
var results = [];
while (row = getRow()) {
results.push({
city: row.value.city,
address: row.value.address
});
}
// make sure to stringify the results :)
send(JSON.stringify(results));
});
}