Groovy - JsonSlurper Parsing JSON file - json

I have a JSON document structured similar to below, and I am trying to parse it in Groovy. Basically for each School (School Info), I want to grab the SCHOOL_COUNTRY and other fields. I am trying this code below but it is not returning what I need. For each school listed (1,000's), I want to grab only specific parts, for instance:
def parseJSON(long id) {
JSONFile fileInstance = JSONFile.get(id)
def json = new JsonSlurper().setType(RELAX).parse(new FileReader(fileInstance.filePath))
def schoolInfo = json.SCHOOL_INFO
def schoolName = json.SCHOOL_INFO.SCHOOL_NAME
schoolInfo.each {
render(schoolInfo.SCHOOL_NAME)
}
}
So basically for each school, just print out the name of the school. The JSON structure:
[{
"SCHOOL_INFO": {
"SCHOOL_COUNTRY": "Finland",
"SCHOOL NAME": "Findland Higher Learning"
},
"LOCATION": {
"LONGITUDE": "24.999",
"LATITUDE": "61.001"
}
}]

I'm not sure if it's the only bug but you can't read schoolInfo.SCHOOL_NAME in each. SCHOOL_NAME is property of json.SCHOOL_INFO so it.SCHOOL_NAME is proper way to access it. Take look at example below:
import groovy.json.JsonSlurper
def jsonAsText = '''[{
"SCHOOL_INFO": {
"SCHOOL_COUNTRY": "Finland",
"SCHOOL NAME": "Findland Higher Learning"
},
"LOCATION": {
"LONGITUDE": "24.999",
"LATITUDE": "61.001"
}
}]'''
def json = new JsonSlurper().parseText(jsonAsText)
def schoolInfo= json.SCHOOL_INFO
schoolInfo.each{
println it."SCHOOL NAME"
}
It prints:
Findland Higher Learning

Here You go:
import groovy.json.JsonSlurper
def t = """[{
"SCHOOL_INFO": {
"SCHOOL_COUNTRY": "Finland",
"SCHOOL NAME": "Findland Higher Learning"
},
"LOCATION": {
"LONGITUDE": "24.999",
"LATITUDE": "61.001"
}
}]"""
def slurper = new JsonSlurper().parseText(t)
slurper.each {
println it.SCHOOL_INFO."SCHOOL NAME"
}
I'm not sure if there should be _ sign in SCHOOL NAME.

println it.SCHOOL_INFO."SCHOOL NAME"
This should work without _ sign.

Related

How can I parse my json file from asset in kotlin?

How can I parse my json file in kotlin. There are many solution for this on the internet but all of them are same however I couldnt find to parse my json file in kotlin.
my json file
{
"A": [
{
"collocation": "above average",
"meaning": "more than average, esp. in amount, age, height, weight etc. "
},
{
"collocation": "absolutely necessary",
"meaning": "totally or completely necessary"
},
{
"collocation": "abuse drugs",
"meaning": "to use drugs in a way that's harmful to yourself or others"
},
{
"collocation": "abuse of power",
"meaning": "the harmful or unethical use of power"
}
],
"B": [
{
"collocation": "back pay",
"meaning": "money a worker earned in the past but hasn't been paid yet "
},
{
"collocation": "back road",
"meaning": "a small country road "
},
{
"collocation": "back street",
"meaning": "a street in a town or city that's away from major roads or central areas"
},
{
"collocation": "back taxes",
"meaning": "taxes that weren't paid when they were due"
},
{
"collocation": "bad breath",
"meaning": "breath that doesn't smell nice"
}],
this way it goes up to the letter W.
I want to parse them all by letter.
my data classes
data class Collocations(
val tag:String,
val collocation: List<Collocation>
)
data class Collocation(
val collocation: String,
val meaning: String
)
But I think these data classes are not correct in my opinion or not effective.
You should just need the Collocation class that you provided here. Then the top-level object could be a Map<String, List<Collocation>> so that the letters are dynamic keys instead.
Using Kotlinx Serialization, it could look like this:
import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
#Serializable
data class Collocation(
val collocation: String,
val meaning: String,
)
fun main() {
val json: String = TODO("get your JSON string here")
val collocations = Json.decodeFromString<Map<String, List<Collocation>>>(json)
val collocationsForA = collocations["A"]
println(collocationsForA)
}

Remove a block from JSON payload using Groovy script

Please find an example payload, where I am trying to remove one block based on the updated date. I am looking to get the message block where the updated date is less than a week from the current date.
[
{
"firstName": "person1",
"lastName": "lname",
"createdDate": "2021-11-18T03:08:50.000Z",
"externalId": null,
"id": "123",
"updatedDate": "2022-03-18T19:33:28.792Z",
"title": "XXXX",
"email": "123#gmail.com",
"enabled": true
},
{
"firstName": "P2",
"lastName": "lname2",
"createdDate": "2021-10-26T19:12:16.000Z",
"externalId": null,
"id": "125",
"updatedDate": "2022-03-01T18:01:19.762Z",
"title": ".",
"email": "125#gmail.com",
"enabled": true
}
]
Using the following code to get the desired result. The remove statement seems to be not removing the collection from body1, or I am dong something wrong here. Tried adding the body1 to the message body, is not working. Tried using the builder, this is giving a completely different error. Any help would be highly appreciated.
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap; import groovy.json.*;
import groovy.json.JsonSlurper;
import groovy.json.JsonBuilder
def Message processData(Message message) {
//Body
def body = message.getBody(java.lang.String) as String;
def body1 = new JsonSlurper().parseText(body)
def jsonOp
def builder = new JsonBuilder()
def today = new Date()
def targetDate = today - 7
pastweek = (targetDate.format("yyyy-MM-dd\'T\'HH:mm:ss'Z'"))
body1.collect.eachWithIndex { it,index->
if ( it.updatedDate < pastweek )
{
it.remove(index)
}
else {
builder {
'firstName' it.firstName
'lastName' it.lastName
'email' it.email
'updatedDate' it.updatedDate
'enabled' it.enabled
}
}
}
def finalJson = builder.toPrettyString()
message.setBody(finalJson.toString())
return message;
}
import groovy.json.*
def Message processData(Message message) {
def body = message.getBody(java.lang.String) as String
def data = new JsonSlurper().parseText(body)
def pastweek = (new Date()-7).format("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
data.removeAll{it.updatedDate < pastweek}
message.setBody(new JsonBuilder(data).toPrettyString())
return message
}

Build JSON as an array element

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"
}
]
}

Groovy - Parse JSON where only certain values exists in response

I am trying to parse a JSON response that has repeating objects with JsonSlurper to compare to a JDBC query. However, I only want to compare objects where a certain values exist within that object.
If I had a response that looks like this, how would I only parse the objects where the country equals USA or Canada, therefore ignoring anything else?
{
"info": [{
"name": "John Smith",
"phone": "2125557878",
"country": {
"value": "USA"
}
},
{
"name": "Jane Smith",
"phone": "2125551212",
"country": {
"value": "USA"
}
},
{
"name": "Bob Jones",
"phone": "4165558714",
"country": {
"value": "Canada"
}
},
{
"name": "George Tucker",
"phone": "4454547171",
"country": {
"value": "UK"
}
},
{
"name": "Jean Normand",
"phone": "4454547171",
"country": {
"value": "France"
}
}]
}
This is what I have in groovy:
def jsonResponse = context.expand('${RESTRequest#Response}')
def parsedJson = new JsonSlurper().parseText(jsonResponse)
def info = parsedJson.info
def jsonDataObjects = []
info.each { json ->
jsonDataObjects.add(Model.buildJSONData(json))
}
I am building a collection of the elements that I need to compare to a database. How do I only add to that collection where the info.country.value = USA or Canada?
I tried using .findAll like this just to test if I could get it to filter by just one of the countries:
def info = parsedJson.info.country.findAll{it.value == "USA"}
But, when I do that, only the value field is kept. I lose the name and phone from the parse.
Thanks in advance for any assistance.
Did you try
def info = parsedJson.info.findAll{it.country.value == "USA"}
?

How to add Json keys to an array list in Django REST framework

I'm using Django REST framework to make an API.
For my serialized models I get a response looks like this:
[GET] http://12.0.0.1/0.5/barrios/?format=json
[
{
"name": "La Julia",
"zone": 1
},
{
"name": "La Floresta",
"zone": 2
}
]
But, what I want looks like this:
{
"barrios": {
"barrio": [
{
"name": "La Julia",
"zone": 1
},
{
"name": "La Floresta",
"zone": 2
}
]
}
}
Any thoughts?
You can override the list() method in your view to get the desired response.
class MyView(..):
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
serializer = self.get_serializer(queryset, many=True)
serializer_data = serializer.data # get the default serialized representation
custom_data = {'barrios': {'barrio': serializer_data}} # custom representation
return Response(custom_data)