How to get values of keys of inside array in json array - java

This is the string that I get which I want to parse as json and get the values of "s", "o", "c" and "p" .
{
"head": {
"vars": [
"s",
"c",
"o",
"p"
]
},
"results": {
"bindings": [
{
"s": {
"type": "uri",
"value": "http://example.org/data/window"
},
"c": {
"type": "uri",
"value": "http://www.w3.org/ns/sosa/FeatureOfInterest"
},
"o": {
"type": "uri",
"value": "http://example.org/data/window104state"
},
"p": {
"type": "uri",
"value": "http://www.w3.org/ns/ssn/hasProperty"
}
},
{
"s": {
"type": "uri",
"value": "http://example.org/data/earth"
},
"c": {
"type": "uri",
"value": "http://www.w3.org/ns/sosa/FeatureOfInterest"
},
"o": {
"type": "uri",
"value": "http://example.org/data/VCAB-DP1-BP-40location"
},
"p": {
"type": "uri",
"value": "http://www.w3.org/ns/sosa/hasSample"
}
}
]
}
}
This is the code I have tried so far:
JsonParser jsonParser = new JsonParser();
JsonElement element = jsonParser.parse(str);
JsonObject obj = element.getAsJsonObject();
JsonObject results = obj.get("results").getAsJsonObject();
for(Map.Entry<String, JsonElement> entry : results.entrySet()) {
JsonArray array = entry.getValue().getAsJsonObject().getAsJsonArray("bindings");
for (JsonElement jsonElement : array) {
for (Map.Entry<String, JsonElement> entry1 : jsonElement.getAsJsonObject().entrySet()) {
System.out.println("Key = " + entry1.getKey() + " Value = " + entry1.getValue() );
}
}
What I want to get is the values of the inside array as such:
"s": "http://example.org/data/earth"
"c": "http://www.w3.org/ns/sosa/FeatureOfInterest"
etc.
Instead I get an error:
Exception in thread "main" java.lang.IllegalStateException: Not a JSON Object: [{"s":{"type":"uri","value":"http://example.org/data/window"},"c":{"type":"uri","value":"http://www.w3.org/ns/sosa/FeatureOfInterest"},"o":{"type":"uri","value":"http://example.org/data/window104state"},
(the whole string).
UPDATE
Thanks to #Deadpool I managed to get the values but now I need to get the "inner" values of the bindings meaning the "value" part of each binding(s,c,p and o). I need only this part and not the "type" part.
This is the result thanks to #Deadpool:
Key = s Value = {"type":"uri","value":"http://example.org/data/window"}
Key = c Value = {"type":"uri","value":"http://www.w3.org/ns/sosa/FeatureOfInterest"}
Key = p Value = {"type":"uri","value":"http://www.w3.org/ns/ssn/hasProperty"}
Key = o Value = {"type":"uri","value":"http://example.org/data/window104state"}
SOLUTION
OK for those interested I managed to get it this the statement that was needed:
System.out.println("Key = " + entry1.getKey() + " Value = " + entry1.getValue().getAsJsonObject().get("value"));
And this is the desired result:
Key = s Value = "http://example.org/data/earth"
Key = c Value = "http://www.w3.org/ns/sosa/FeatureOfInterest"
Key = o Value = "http://example.org/data/VCAB-DP1-BP-40location"
Key = p Value = "http://www.w3.org/ns/sosa/hasSample"

The problem is in this statement bindings is a JsonArray, get it as JsonArray directly
JsonArray array = entry.getValue().getAsJsonObject().getAsJsonArray("bindings");
Solution
for(Map.Entry<String, JsonElement> entry : results.entrySet()) {
JsonArray array = entry.getValue().getAsJsonArray();
for (JsonElement jsonElement : array) {
for (Map.Entry<String, JsonElement> entry1 : jsonElement.getAsJsonObject().entrySet()) {
System.out.println("Key = " + entry1.getKey() + " Value = " + entry1.getValue() );
}
}

You can use Declarative Stream Mapping (DSM) stream parsing library to easily capture data from XML or JSON
First of all, you must define the mapping between JSON data and your fields in yaml or JSON format.
Here are the mapping definitions:
result:
type: array
path: /results/bindings/(s|c|o|p) // regex
fields:
key:
path: type
value:
Java class that you want to deserialize:
public class KeyValue{
public String key;
public String value
}
Java Code to parse JSON:
DSM dsm=new DSMBuilder(new File("path/to/mapping.yaml")).create(KeyValue.class);
List<KeyValue> list= (List<KeyValue>)dsm.toObject(jsonData);
// write root object as json
dsm.getObjectMapper().writerWithDefaultPrettyPrinter().writeValue(System.out, list);
Here is output:
[ {
"key" : "uri",
"value" : "http://example.org/data/window"
}, {
"key" : "uri",
"value" : "http://www.w3.org/ns/sosa/FeatureOfInterest"
}, {
"key" : "uri",
"value" : "http://example.org/data/window104state"
}, {
"key" : "uri",
"value" : "http://www.w3.org/ns/ssn/hasProperty"
}, {
"key" : "uri",
"value" : "http://example.org/data/earth"
}, {
"key" : "uri",
"value" : "http://www.w3.org/ns/sosa/FeatureOfInterest"
}, {
"key" : "uri",
"value" : "http://example.org/data/VCAB-DP1-BP-40location"
}, {
"key" : "uri",
"value" : "http://www.w3.org/ns/sosa/hasSample"
} ]

Related

How to merge two JSON string

I have two JSON strings, I want to merge these two response string into a single one. Is there any way to merge these two JSON string using java ?
String str1 = "{
"data" : {
"values" : {
"name" : "kiran",
"age" : "24"
}
}
}"
String str2 = "{
"data" : {
"values" : {
"name" : "Mamu",
"age" : "26"
}
}
}"
I wnat to merge these two JSON string as follows
String mergeResult = "{
"data" : {
"values" : [
{
"name" : "kiran",
"age" : "24"
},
{
"name" : "Manu",
"age" : "26"
}
]
}
}"
From your example JSON it looks like there can be many more input objects than two, so I'd use a JSON to JSON transform via JOLT library (https://github.com/bazaarvoice/jolt) as follows:
Form a JSON array of all the input {"data" : ...} objects (either by collecting the original objects and putting them in a List before serialization or just manually by concatenating their JSONs with square brackets):
[
{
"data": {
"values": {
"name": "kiran",
"age": "24"
}
}
},
{
"data": {
"values": {
"name": "Mamu",
"age": "26"
}
}
}
]
Use the JOLT spec:
[
{
"operation": "shift",
"spec": {
"*": {
"data": {
"values": {
"#": "data.values[]"
}
}
}
}
}
]
The resulting JSON:
{
"data" : {
"values" : [ {
"name" : "kiran",
"age" : "24"
}, {
"name" : "Mamu",
"age" : "26"
} ]
}
}
You can test or modify the spec yourself at http://jolt-demo.appspot.com before using it in your application.
Here's what Java side might look like:
Resource transformationSpec = ...
String inputJson = ...
List<Object> specs = JsonUtils.jsonToList(transformationSpec.getInputStream());
Chainr chainr = Chainr.fromSpec(specs);
Object inputObject = JsonUtils.jsonToObject(inputJson);
Object transformedObject = chainr.transform(inputObject);
String transformedJson = JsonUtils.toJsonString(transformedObject);
Library Josson & Jossons has concatenate operation to combine array from datasets.
https://github.com/octomix/josson
Jossons jossons = new Jossons();
jossons.putDataset("resp1", Josson.fromJsonString(
"{" +
" \"data\": {" +
" \"values\": {" +
" \"name\": \"kiran\"," +
" \"age\": \"24\"" +
" }" +
" }" +
"}"));
jossons.putDataset("resp2", Josson.fromJsonString(
"{" +
" \"data\": {" +
" \"values\": {" +
" \"name\": \"Mamu\"," +
" \"age\": \"26\"" +
" }" +
" }" +
"}"));
JsonNode mergeValues = jossons.evaluateQuery(
"resp1->data.toArray() <+< resp2->data.toArray()");
System.out.println(mergeValues.toPrettyString());
JsonNode mergeResult = Josson.create(mergeValues).getNode(
"toObject('values').toObject('data')");
System.out.println(mergeResult.toPrettyString());
mergeValues
[ {
"name" : "kiran",
"age" : "24"
}, {
"name" : "Mamu",
"age" : "26"
} ]
mergeResult
{
"data" : {
"values" : [ {
"name" : "kiran",
"age" : "24"
}, {
"name" : "Mamu",
"age" : "26"
} ]
}
}
May be not the most efficient solution but very simple one would be to parse each String into a Map (or specific POJO if you have one) and merge them as maps, and than serialize back into Json String. To parse a json string to map or a specific POJO you can use Jackson library - method readValue() of ObjectMapper Or Gson library. Also, I wrote my own simple wrapper over Jackson library that simplifies the use. Class JsonUtils is available as part of MgntUtils library (written and maintained by me). This class just has the methods that allow you to parse and de-serialize from/to Json String from/to a class instance. So your code could be as follows:
public String mergeJsonStrings(String str1, Str2) throws IOException {
Map<String, Object> map1 = convertJsonStringToMap(str1);
Map<String, Object> map2 = convertJsonStringToMap(str2);
Map<String, Object> dataMap1 = (Map<String, Object>)map1.get("data");
Map<String, Object> valuesMap1 = (Map<String, Object>)dataMap1.get("values");
Map<String, Object> dataMap2 = (Map<String, Object>)map2.get("data");
Map<String, Object> valuesMap2 = (Map<String, Object>)dataMap2.get("values");
valuesMap1.putAll(valuesMap2);
return convertMapToJsonString(map1);
}
Map<String, Object> convertJsonStringToMap(String str) throws IOException {
return JsonUtils.readObjectFromJsonString(str, Map.class);
}
Strong convertMapToJsonString(Map<String,Object> map) throws JsonProcessingException{
return JsonUtils.writeObjectToJsonString(map);
}
This example uses MgntUtils library to parse and serialize JSON but of course you can use Jackson, Gson or any other library you want. MgntUtils library available as Maven artifact and on Github (including source code and Javadoc)

JSON to JSON Transform of input sample using any existing java library/tools

Input:
{
"Student": {
"name" :"abc",
"id" : 588,
"class : "12"
}
}
Reqired Output:
{
"Student": {
"key" :"name",
"value":"abc",
"key" :"id",
"value":"588",
"key" :"class",
"value":"12"
}
}
Your output json invalid. Json object can not duplicate key .
You can use the library org.json and do something like this:
JSONObject jsonObject = new JSONObject(inputJson);
JSONObject outputJson = new JSONObject();
JSONArray array = new JSONArray();
for (Object key : jsonObject.keySet()) {
JSONObject item = new JSONObject();
String keyStr = (String)key;
Object keyvalue = jsonObj.get(keyStr);
item.put(keyStr, keyvalue);
array.put(item);
}
outputJson.put("Student", array);
System.out.println(json.toString());
Output :
{
"Student": [
{
"key": "name",
"value": "abc"
},
{
"key": "id",
"value": "588"
},
{
"key": "class",
"value": "12"
}
]
}
Similar to the other answer, the desired output JSON format is not valid.
The closest valid output would be
{
"Student" : [ {
"key" : "name",
"value" : "abc"
}, {
"key" : "id",
"value" : 588
}, {
"key" : "class",
"value" : "12"
} ]
}
This can be generated via Jolt with the following spec
[
{
"operation": "shift",
"spec": {
"Student": {
"name": {
"$": "Student[0].key",
"#": "Student[0].value"
},
"id": {
"$": "Student[1].key",
"#": "Student[1].value"
},
"class": {
"$": "Student[2].key",
"#": "Student[2].value"
}
}
}
}
]
This is easy to solve with JSLT if we assume the output is made valid JSON by making an array of key/value objects like the other respondents do.
The array function converts an object into an array of key/value objects exactly like you ask for, so the transform becomes:
{"Student" : array(.Student)}

How to set nested JSON data to datatables?

I have a (nested) data structure containing objects and arrays. And trying to sent datatables but only one value displaying.
JSON data:
{
"data": [{
"name": "name1",
"value": "value1",
"list": [{
"sname": "sname1",
"svalue": "svalue1"
}, {
"sname": "sname2",
"svalue": "svalue2"
}]
}]
}
JSON data getting through URL by using Java.
jQuery code:
var pk = $("#pk").val();
console.log(pk);
url = "/register/search?id=" + pk;
console.log(url);
$('#largeTable').DataTable({
"ajax": url,
"bDestroy": true,
"columns": [{
"data": "name"
},
{
"data": "value"
},
{
"data": "list.1.sname"
},
{
"data": "list.1.svalue"
},
{
"data": null,
"defaultContent": editview
}
]
});
Here it is possible to display either first or second list values by using list.1 or list.0
But I want two values at a time.
If you used render or mRender you can do what you want with the object. For example you can traverse the array like in this example.
$('#largeTable').DataTable({
"columnDefs": [
{"targets": [0], "title":"name", "data":"name"},
{"targets": [1], "title":"value", "data":"value"},
{"targets": [2], "title":"list", "data":"list", "type":"html"
"render":function(data){
var listArray = data;
var listHtml = "";
for(var i=0;i<listArray.length;i++) {
listHtml += listArray[i].sname + " " + listArray[i].svalue + "<br>";
}
return listHtml;
},
}]
});
$.ajax({
"type":"GET",
"url":url,
"success":function(data,status) {
var jsonData = $.parseJSON(data);
$('#largeTable').dataTable().fnAddData(jsonData);
}
Your list in json data structure is an array. So, you should use
list.forEach(function(element) {
//console.log(element);
});
You could create an object and build JSON dynamically and set it to "columns" array.
Here is an example:
// make an empty object
var myObject = {};
// set the "list1" property to an array of strings
myObject.list1 = ['1', '2'];
// you can also access properties by string
myObject['list2'] = [];
// accessing arrays is the same, but the keys are numbers
myObject.list2[0] = 'a';
myObject['list2'][1] = 'b';
myObject.list3 = [];
// instead of placing properties at specific indices, you
// can push them on to the end
myObject.list3.push({});
// or unshift them on to the beginning
myObject.list3.unshift({});
myObject.list3[0]['key1'] = 'value1';
myObject.list3[1]['key2'] = 'value2';
myObject.not_a_list = '11';

MongoDB $regex query for "end with" particular char

I am not able to remove object from an array named Matrix for a Key match
BasicDBObject where = new BasicDBObject();
where.put("INSTITUTION_ID", instid);
where.put("RuleID", ruleid);
BasicDBObject obj1 = new BasicDBObject();
obj1.put("Matrix.Key",new BasicDBObject("$regex","/"+json.getString("Code")+"$/"));
collection.update(where,new BasicDBObject("$pull", obj1));
The code above is not removing object from array. The structure of the array can be found below
"Matrix" : [
{
"Key" : "6M",
"value" : "Queue"
},
{
"Key" : "6N",
"value" : "Queue"
},
{
"Key" : "6O",
"value" : "Queue"
}]
Command-line client
I suggest that before writing queries in Java notation, you first test them in the mongo console, with the regular JavaScript syntax. The following query works for me.
Data
db.matrix.insert(
{
INSTITUTION_ID: 1,
RuleID: 2,
Matrix: [
{
"Key": "6M",
"value": "Queue"
},
{
"Key": "6N",
"value": "Queue"
},
{
"Key": "6O",
"value": "Queue"
}
]
})
Query
db.matrix.update(
{
INSTITUTION_ID: 1,
RuleID: 2,
},
{
$pull:
{
Matrix:
{
Key:
{
$regex: /M$/
}
}
}
})
Data after the update
{
"INSTITUTION_ID" : 1.0000000000000000,
"RuleID" : 2.0000000000000000,
"Matrix" : [
{
"Key" : "6N",
"value" : "Queue"
},
{
"Key" : "6O",
"value" : "Queue"
}
]
}
Java
I am not sure how this update query should be represented in Java, but try this:
BasicDBObject where =
new BasicDBObject()
.put("INSTITUTION_ID", instid);
.put("RuleID", ruleid);
BasicDBObject update =
new BasicDBObject("$pull",
new BasicDBObject("Matrix",
new BasicDBObject("Key",
new BasicDBObject("$regex",
java.util.regex.Pattern.compile(json.getString("Code") + "$")))));
collection.update(where, update);

How can I parse this syntax of JSON?

I've been trying to parse this portion of JSON output, but I cannot figure out how to. I'm trying to pull out "140 New Montgomery St". Can anyone tell me how? Below I will include the JSON and my already working JSON parsing code.
{
"businesses" : [{
"display_phone" : "+1-415-908-3801",
"id" : "yelp-san-francisco",
"is_claimed" : true,
"is_closed" : false,
"image_url" : "http://s3-media2.ak.yelpcdn.com/bphoto/7DIHu8a0AHhw-BffrDIxPA/ms.jpg",
"location" : {
"address" : [
"140 New Montgomery St"
],
"city" : "San Francisco",
"neighborhoods" : [
"SOMA"
],
"postal_code" : "94105",
"state_code" : "CA"
},
"mobile_url" : "http://m.yelp.com/biz/4kMBvIEWPxWkWKFN__8SxQ",
"name" : "Yelp",
}
],
"region" : {
"center" : {
"latitude" : 37.786138600000001,
"longitude" : -122.40262130000001
},
"span" : {
"latitude_delta" : 0.0,
"longitude_delta" : 0.0
}
},
"total" : 10651
}
JSONObject json = new JSONObject(rawData);
JSONArray businesses;
businesses = json.getJSONArray("businesses");
for (int i = 0; i < businesses.length(); i++) {
JSONObject business = businesses.getJSONObject(i);
closed = business.get("is_closed").toString();
//...
//...
}
JSONObject location = business.getJSONObject("location");
JSONArray address = location.getJSONArray("address");
String address1 = address.get(0);
//...
//...

Categories