JsonQuery
A Java Based Query Engine For JSON
Install / Use
/learn @rdbeach/JsonQueryREADME
JsonQuery
A Java based query engine for JSON.
A quick look
NOTE The package currently includes a simple SQL engine, however, it is still very much in the experimental stages.
JsonQuery gives you Java tools for consuming, traversing, querying, editing, and producing JSON. It uses the Gson library for serialization and deserialization.
It consists of two parts:
1) Single node operations.
2) JSQL queries (JSON Strucured Query Language)
The single node operators allow you to maniputate the JSON tree one node at a time. For instance, a deeply nested JSON field
"company":{
"sales":{
"international":{
"reps":[
{
"name":"bob",
"start date":5-17-06",
"monthly commission":5000
},
{
"name":"stu",
"start date":12-10-06",
"monthly commission":10000
},
{
"name":"bill",
"start date":1-23-07",
"monthly commission":4000
}
]
}
}
}
can be extracted as follows:
$.val("company.sales.international.reps.0.name");
// bob
or updated like this:
$.set("company.sales.international.reps.0.monthly commission",6000);
As you can see, you create a "path" string to target a particular node.
The JSQL Engine allows you to run SQL style queries on the JSON structure, like this:
$.jsql("Select name from company:reps.? where monthly commision>5000)
// The result set would return stu
The query returns a result set, which is a set of matching nodes.
This project does not address binding JSON to Java classes. Instead, the JSON information is encapsulated in a dynamic tree structure. From there, you can do with it whatever you want- write it to a class, save it to a database, or send a JSON response back to your client app after processing a request.
Implementation Notes
To use JsonQuery, you will first need to add the Gson library to your project. You may download it here:
https://code.google.com/p/google-gson/downloads/list
To run the test file, JsonQueryTest.java, you will also need to implement the benelog/multiline project:
https://github.com/benelog/multiline
Alternatively, you can edit the JsonQueryTest.java file so that it does not contain the multiline strings.
Usage
Part I: Single Node Operations
Here is an example.
Start with a JSON string:
{
"empID": 100,
"name": "Robert",
"permanent": false,
"address": {
"street": "Foolhill Blvd",
"city": "Pasadena",
"zipcode": 91011
},
"phoneNumbers": [
1234567,
9876543
],
"role": "Java Developer",
"employed":true,
"cities": [
"Los Angeles",
"New York"
],
"properties": {
"age": "28 years",
"salary": "$6000"
}
}
The variable msg will contain the JSON string above.
Convert the JSON string to a JsonQuery object.
// create JsonQuery object
JsonQuery $ = JsonQuery.fromJson(msg);
// or recreate the JSON string from the JsonQuery object
out($.toJson()); // out means System.out.println.
// {"empID":100,"address":{"zipcode":91011,"city":"Pasadena","street":"Foolhill Blvd"},"role":"Java Developer","cities":["Los Angeles","New York"],"permanent":false,"name":"Robert","phoneNumbers":[1234567,9876543],"properties":{"salary":"$6000","age":"28 years"},"employed":true}
Retrieve some properties from the newly created object:
// Whats my city? (str gets a string)
out($.str("address.city"));
// Pasadena
//You can also use "val", but this returns Object, so you must cast to the type you want
String city = (String) $.val("address.city");
out(city);
// Pasadena
// Whats my phone # (i gets an integer)
out($.i("phoneNumbers.1"));
// 9876543
Set some properties:
// Change my city like this: (If set cannot find the path to city, it will do nothing)
$.set("address.city","san fran");
// or like this: (Like set, if get cannot find the path, it simply returns)
$.get("address.city").set("san fran");
// or like this: (If put cannot find the path to city, it will create it and set the value)
$.put("address.city","san fran");
// or like this: (Like put, node will find or create the path to city, the field will be updated with set)
$.node("address.city").set("san fran");
// Print new address in json format
out($.toJson("address"));
// {"zipcode":91011,"city":"san fran","street":"Foolhill Blvd"}
// If you wish to add a bunch of things to address, you probably should "get" the address key first, and then make your additions:
$.get("address").put("city","las vegas").put("city2","new york").put("city3","chicago")...
// Update phone numbers: Use "add" to add to an array, or "set" to change existing values.
JsonQuery phoneNumbers = $.get("phoneNumbers");
phoneNumbers.add(0,5555555);
phoneNumbers.remove(1);
// Print phone numbers in json format
out(phoneNumbers.toJson());
// [5555555,9876543]
Use a JSON string to add to the JsonQuery object tree (with jput):
// jput, jadd, and jset function like their equivalents, put, add, and set, except that they take a JSON
// string as the "value" argument.
// Add my hobbies
$.jput("hobbies","[\"tennis\",\"hiking\",\"swimming\"]");
// Print the whole thing again
out($.toJson());
// {"empID":100,"address":{"zipcode":91011,"city":"san fran","street":"Foolhill Blvd"},"role":"Java Developer","cities":["Los Angeles","New York"],"hobbies":["tennis","hiking","swimming"],"permanent":false,"name":"Robert","phoneNumbers":[5555555,9876543],"properties":{"salary":"$6000","age":"28 years"},"employed":true}
More manipualtion: Removing stuff. Changing stuff. etc.
// Actually I don't like swimming
$.remove("hobbies.2");
out($.toJson("hobbies"));
// ["tennis","hiking"]
// Oh no, I lost my job
$.remove("role");
$.set("employed",false);
// Print the whole thing again
out($.toJson());
// {"empID":100,"address":{"zipcode":91011,"city":"san fran","street":"Foolhill Blvd"},"cities":["Los Angeles","New York"],"hobbies":["tennis","hiking"],"permanent":false,"name":"Robert","phoneNumbers":[5555555,9876543],"properties":{"salary":"$6000","age":"28 years"},"employed":false}
// Add more to the JSON object tree
$.jput("properties.pets","{\"cat\":\"Mr Wiggles\",\"dog\":\"Happy\"}");
out($.toJson("properties"));
// {"pets":{"cat":"Mr Wiggles","dog":"Happy"},"salary":"$6000","age":"28 years"}
// You can also append to the JSON object like this
// first remove pets
$.remove("properties.pets");
/** myPets:
{
"cat":"Mr Happy",
"dog":"Wiggles"
}
*/
// create a pets JSON object
JsonQuery pets = JsonQuery.fromJson(myPets);
// add it
$.put("properties.pets",pets);
// print all
out($.toJson());
// {"empID":100,"address":{"zipcode":91011,"city":"san fran","street":"Foolhill Blvd"},"cities":["Los Angeles","New York"],"hobbies":["tennis","hiking"],"permanent":false,"name":"Robert","phoneNumbers":[5555555,9876543],"properties":{"pets":{"cat":"Mr Happy","dog":"Wiggles"},"salary":"$6000","age":"28 years"},"employed":false}
Another example:
/**
{
"data": {
"translations": [
{
"translatedText": "Hello world"
}
]
}
}
*/
Grab the "translatedText" value like this:
JsonQuery $ = JsonQuery.fromJson(msg);
out(
$.val("data.translations.0.translatedText")
);
// Hello world
// You can set a value like this
$.set("data.translations.0.translatedText","Bonjour");
// Str gets the value of the node as a string (regardless of type)
out(
$.str("data.translations.0.translatedText")
);
// Bonjour
// Adds a translation to the translations array
$.add("data.translations","Bonjour:hello");
// Adds a Json Object to the second position in the translations array.
$.jadd("data.translations",1,"{\"french\":\"Bonjour\",\"english\":\"hello\"}");
out(
$.get("data.translations").toJson()
);
// [{"translatedText":"Bonjour"},{"english":"hello","french":"Bonjour"},"Bonjour:hello"]
// You can use "get"
