Related
I have some issue finding the right way to filter in my input json file using jolt as described in the following:
Input :
{
"test1": 2242,
"test2": 23456,
"description": "desc, desc, desc",
"name1": "foo",
"active": true,
"date1": "xx-xx-xx",
"date2": "xx-xx-xx",
"grade": "A",
"quantity": 10,
"information": "info, info, info",
"favorite": "Y",
"maxValue": 100,
"approachTypeMin[zone=MAR, method=a]": "12",
"approachTypeMax[zone=MAR, method=a]": "50",
"approachTypeMin[zone=NOR, method=b]": "3",
"approachTypeMax[zone=NOR, method=b]": "10"
}
This is my Spec
[
{
"operation": "shift",
"spec": {
"test1": "value1",
"test2": "value2",
"description": "desc1",
"name1": "nameValue",
"active": {
"true": {
"#Active": "status"
},
"false": {
"#Inactive": "status"
}
},
"date1": "beginDate",
"date2": "endDate",
"grade": {
"*": {
"$": "testGrade.value",
"#(2,type)": "testGrade.type",
"#2": "testGrade.defaultValue"
}
},
"quantity": "qtn",
"additionalInfo": "information",
"favorite": "fvt",
"maxValue": "max",
"approachType*, method=*]": "test.&(0,2)"
}
}
]
This is my actual Output
{
"value1" : 2242,
"value2" : 23456,
"desc1" : "desc, desc, desc",
"nameValue" : "foo",
"status" : "Active",
"beginDate" : "xx-xx-xx",
"endDate" : "xx-xx-xx",
"testGrade" : {
"value" : "A",
"defaultValue" : "2"
},
"qtn" : 10,
"fvt" : "Y",
"max" : 100,
"test" : {
"A" : [ "12", "50" ],
"B" : [ "3", "10" ]
}
}
My issue is that i can't find a way to get something like the result above depending on the grade(e.g grade A==Approach method):
{
"value1": 2242,
"value2": 23456,
"desc1": "desc, desc, desc",
"nameValue": "foo",
"status": "Active",
"beginDate": "xx-xx-xx",
"endDate": "xx-xx-xx",
"value": "X",
"testGrade": {
"type": "A",
"defaultValue": "2"
},
"qtn": "10",
"fvt": "Y",
"max": "100",
"convertedApproachMin": 12,
"convertedApproachMax": 50
}
Thanks for any help!
Need to divide key names starting with approachType one more time in order to seperate them by means of Min and Max, to derive the lower case grade to match the extracted methods (a and b).
So, use the following specs :
[
{
"operation": "shift",
"spec": {
"test1": "value1",
"test2": "value2",
"description": "desc1",
"name1": "nameValue",
"active": {
"true": {
"#Active": "status"
},
"false": {
"#Inactive": "status"
}
},
"date1": "beginDate",
"date2": "endDate",
"grade": "&",
"quantity": "qtn",
"additionalInfo": "information",
"favorite": "fvt",
"maxValue": "max",
"approachType*\\[zone*, method=*]": "cA&(0,1).&(0,3)"
}
},
{
"operation": "modify-overwrite-beta",
"spec": {
"grade_l": "=toLower(#(1,grade))"
}
},
{
"operation": "shift",
"spec": {
"*": "&",
"grade_l": {
"*": {
"#(2,grade)": "testGrade.value",
"#2": "testGrade.defaultValue",
"#(2,cAMin.&)": "convertedApproachMin",
"#(2,cAMax.&)": "convertedApproachMax"
}
}
}
},
{
"operation": "remove",
"spec": {
"grade": "",
"cA*": ""
}
}
]
the demo on the site http://jolt-demo.appspot.com/ :
Currently I'm using rest-assured to hit an endpoint and in turn store any JSON data matches via an ArrayList and HashMap.
I can see that I'm receiving a response back, but how do I loop over an ArrayList when it contains an internal HashMap?
As you can see from the JSON data below, I'm expecting to output all values / matches stored within the ArrayList.
My Code:
public void apiTest() {
String position = "Attacker";
String role = "PLAYER";
Response response = given()
.spec(footballCompetitions_requestSpecification)
.when().get(EndPoint.TEAMS + EndPoint.SQUAD);
ArrayList<Map<String, ?>> allPlayers = response.path
("squad.findAll { it.role == '%s' }.findAll { it.position == '%s' }", position, role);
Example JSON Data:
{
"id": 66,
"area": {
"id": 2072,
"name": "England"
},
"activeCompetitions": [
{
"id": 2021,
"area": {
"id": 2072,
"name": "England"
},
"name": "Premier League",
"code": "PL",
"plan": "TIER_ONE",
"lastUpdated": "2019-01-03T23:39:45Z"
},
{
"id": 2001,
"area": {
"id": 2077,
"name": "Europe"
},
"name": "UEFA Champions League",
"code": "CL",
"plan": "TIER_ONE",
"lastUpdated": "2018-12-13T18:55:02Z"
}
],
"name": "Manchester United FC",
"shortName": "Man United",
"tla": "MNU",
"crestUrl": "http://upload.wikimedia.org/wikipedia/de/d/da/Manchester_United_FC.svg",
"address": "Sir Matt Busby Way Manchester M16 0RA",
"phone": "+44 (0161) 8688000",
"website": "http://www.manutd.com",
"email": "enquiries#manutd.co.uk",
"founded": 1878,
"clubColors": "Red / White",
"venue": "Old Trafford",
"squad": [
{
"id": 3188,
"name": "David De Gea",
"position": "Goalkeeper",
"dateOfBirth": "1990-11-07T00:00:00Z",
"countryOfBirth": "Spain",
"nationality": "Spain",
"shirtNumber": 1,
"role": "PLAYER"
},
{
"id": 3331,
"name": "Marcus Rashford",
"position": "Attacker",
"dateOfBirth": "1997-10-31T00:00:00Z",
"countryOfBirth": "England",
"nationality": "England",
"shirtNumber": 10,
"role": "PLAYER"
},
{
"id": 3372,
"name": "Anthony Martial",
"position": "Attacker",
"dateOfBirth": "1995-12-05T00:00:00Z",
"countryOfBirth": "France",
"nationality": "France",
"shirtNumber": 11,
"role": "PLAYER"
},
{
"id": 3662,
"name": "Romelu Lukaku",
"position": "Attacker",
"dateOfBirth": "1993-05-13T00:00:00Z",
"countryOfBirth": "Belgium",
"nationality": "Belgium",
"shirtNumber": 9,
"role": "PLAYER"
},
If you are using Java 8 or higher, then just iterate over the List first and over the Map in a nested iteration using lambda expressions:
public static void main(String[] args) {
List<Map<String, ?>> jsonList = new ArrayList<>();
Map<String, String> mapOne = new HashMap<String, String>();
mapOne.put("id", String.valueOf(66));
mapOne.put("area", "Some Area");
jsonList.add(mapOne);
jsonList.forEach(map -> {
map.forEach((key, value) -> {
System.out.println(key + ": " + value);
});
});
}
The thing you have to take care of is the String representation of value, since it is a Map<String, ?> in your code and a Map<String, String> in my example, what may lead to problems if you directly use the above example's System.out.println(key + ": " + value);.
First iterate over the list, then iterate over the Map:
for (Map<String, ?> map : allPlayers) {
for (String key : map.keySet()) {
Object player = map.get(key);
// ...
}
}
I want to get the value of city from the below httpResponse (JSON Response) where fruit is Apple. I am unable to find a way to add this condition to my groovy script.
{
"userInformation": {
"Name": "John",
"Location": "India"
},
"details": [
{
"fruit": "Apple",
"color": "Red",
"city": "New Delhi",
"luckyNumber": 10
},
{
"fruit": "Banana",
"color": "yellow",
"city": "Goa",
"luckyNumber": 12
}
]
}
JsonSlurper is what you need. It parses JSON object to a plain Map which can be then easily navigated to find the desired value.
import groovy.json.JsonSlurper
def input = '''{
"userInformation": {
"Name": "John",
"Location": "India"
},
"details": [
{
"fruit": "Apple",
"color": "Red",
"city": "New Delhi",
"luckyNumber": 10
},
{
"fruit": "Banana",
"color": "yellow",
"city": "Goa",
"luckyNumber": 12
}
]
}
'''
def slurped = new JsonSlurper().parseText(input)
slurped.details.find { it.fruit == 'Apple' }?.city
I have the following JSON:
{
"items": [
{
"id": "1",
"name": "John",
"location": {
"town": {
"id": "10"
},
"address": "600 Fake Street",
},
"creation_date": "2010-01-19",
"last_modified_date": "2017-05-18"
},
{
"id": "2",
"name": "Sarah",
"location": {
"town": {
"id": "10"
},
"address": "76 Evergreen Street",
},
"creation_date": "2010-01-19",
"last_modified_date": "2017-05-18"
},
{
"id": "3",
"name": "Hamed",
"location": {
"town": {
"id": "20"
},
"address": "50 East A Street",
},
"creation_date": "2010-01-19",
"last_modified_date": "2017-05-18"
}
]
}
And I need to get something like this, count how many times each townId appears:
[ { "10": 2 }, {"20": 1 }]
I'm trying to find the most eficient way to do this. Any idea?
Most efficient way is to load the String in a StringBuilder and remove all line breaks and white spaces. Then search for index of "town":{"id":" string (town start index) and then search for the end index (String `"}'). Using the 2 indexes you can extract town ids and count them.
No need to deserialize the JSON into POJO objects:) and extract values by xpath from the POJOs.
For example, I have a JSON database like this:
[
{
"address": "America",
"location": {
"lng": 106.669633,
"lat": 10.771883
},
"name": "724 (100) Pyrmon"
},
{
"address": "America",
"location": {
"lng": 106.668821,
"lat": 10.767997
},
"name": "900 (100) Glassdor"
},
{
"address": "328A, Đường Lê Hồng Phong, Ward 1, Quận 10, TP.HCM, Việt Nam",
"location": {
"lng": 106.676276,
"lat": 10.763239
},
"name": "Booking Office Of Phuong Trang Buslines"
},
{
"address": "America",
"location": {
"lng": 106.690329,
"lat": 10.768556
},
"name": "Opposite Pyrmont"
},
{
"address": "America",
"location": {
"lng": 106.691759,
"lat": 10.763937
},
"name": "150 Washington"
},
{
"address": "America",
"location": {
"lng": 106.681683,
"lat": 10.76965
},
"name": "596 - 598 Nguyễn Đình Chiểu"
},
{
"address": "America",
"location": {
"lng": 106.690158,
"lat": 10.77509
},
"name": "17 Bà Huyện Thanh Quan"
},
{
"address": "America",
"location": {
"lng": 106.699749,
"lat": 10.774052
},
"name": "101 Jase"
},
{
"address": "America",
"location": {
"lng": 106.682621,
"lat": 10.778547
},
"name": "274 Lost Region"
},
{
"address": "America",
"location": {
"lng": 106.67305,
"lat": 10.765617
},
"name": "66 Office Base"
},
{
"address": "America",
"location": {
"lng": 106.689733,
"lat": 10.763817
},
"name": "118 Yen The"
},
{
"address": "America",
"location": {
"lng": 106.69313,
"lat": 10.765497
},
"name": "112 Glangdie"
},
]
Now I have to make an algorithm (in any programming language, if in Java, it will be good) that will input the latitude, longitude, and the distance D . The output will be JSON data that contain the information of nearby places that have the distance to the input distance smaller than D .
I have researched about this algorithm, especially on Wikipedia, http://en.wikipedia.org/wiki/Geographical_distance#Singularities_and_discontinuity_of_latitude.2Flongitude.
But I cannot find a way to query from the database, if the database is BIG, I have to query each row(or each JSON Object in this case) to compare with the chosen location, that will be a very slow performance.
How can I do this?
You can try to reduce comparisons by filtering locations inside circumscribed square around circle with input radius. In SQL it looks like: WHERE lng>=(:lng - :radius) AND lng<=(:lng + :radius) AND lat>=(:lat - :radius) AND lat<=(:lat + :radius), where :lng, :lat - input coordinates, :radius - input radius in radians.