How to parse JSON and access a value - json

From this,
{
“students”: [
{
“name”: “test1”,
"id": 1,
"created_at": "2019-03-13T21:34:30Z",
"updated_at": "2019-03-13T21:34:30Z",
“title”: "My test ticket2",
"description": “My test description!”
}
],
"count": 1
}
How can I get the value of id, description and count? I did:
JSON.parse(response)
but I am not sure how to get the value.

You need to parse twice, if you just parse once you will get the error:
TypeError: no implicit conversion of Hash into String
you should do like that:
parsed_response = JSON.parse(response.to_json)
Then you can get the values as you need:
parsed_response['students'][0]['id']
You can also use the dig method if your ruby version is higher than 2.3:
parsed_response.dig('students', 0, 'id')
=> 1

JSON.parse returns hash.
Fetching information about student:
parsed_response = JSON.parse(response)
parsed_response['students'].first['id']
parsed_response['students'].first['name']
parsed_response['students'].first['description']
If you have more than one values, iterate over them with each.
Fetching count:
parsed_response = JSON.parse(response)
parsed_response['count']
Instead of [] you can use fetch (parsed_response.fetch('students')). Please keep in mind, that fetch raises an error when the key is missing.

Related

Parse multi level JSON with Ruby

I am trying to parse the JSON file below. The problem is I cannot return "Mountpoint" as a key. It only gets parsed as a value. This is the command I am using to parse it json_data = JSON.parse(readjson). The reason I guess that it's a key is because if I run json_data.keys only EncryptionStatus and SwitchName are returned. Any help would be greatly appreciated.
{
"EncryptionStatus": [
{
"MountPoint": "C:",
"VolumeStatus": "FullyEncrypted"
},
{
"MountPoint": "F:",
"VolumeStatus": "FullyEncrypted"
},
{
"MountPoint": "G:",
"VolumeStatus": "FullyEncrypted"
},
{
"MountPoint": "H:",
"VolumeStatus": "FullyEncrypted"
}
],
"SwitchName": [
"LAN",
"WAN"
]
}
I tried using dig as a part of my JSON.parse but that didn't seem to help me.
JSON data can have multiple levels.
Your JSON document is a
Hash (Dictionary/Map/Object in other languages) that has two keys ("EncryptionStatus", "SwitchName"),
The value for the "EncryptionStatsu" key is an Array of Hashes (with keys "MountPoint" and "VolumeStatus").
# assuming your JSON is in a file called "input.json"
data = File.read("input.json")
json = JSON.parse(data)
json["EncryptionStatus"].each do |encryption_status|
puts "#{encryption_status["MountPoint"]} is #{encryption_status["VolumeStatus"]}"
end
This will print out
C: is FullyEncrypted
F: is FullyEncrypted
G: is FullyEncrypted
H: is FullyEncrypted
If you want to access a specific item you can look at the dig method. E.g.
json.dig("EncryptionStatus", 3)
Would return the information for mountpoint "H"

How to validate entire JSON with 1 dynamic field with JMeter

I have a JSR223 Assertion in JMeter that validates entire JSON response and its working.
The problem is that each time I insert data in DB one of JSON fields changes and validation fails.
How could I skip that dynamic field from response validation?
Response JSON example:
[
{
"id": "273444",
"trxDateTime": "2019-03-25T22:38:16Z",
"merchantName": "MerchECOM1",
"merchantTransId": "1r1vXue4qn",
"trxType": "Payment",
"paymentBrand": "MasterCard",
"amount": 20.00,
"currencyCode": "AUD",
"status": "Declined",
"statusResponseMessage": null,
"customerAccount": "123456"
}
]
JSR223 Assertion:
def expected = new groovy.json.JsonSlurper().parseText(vars.get('expected1'))
def actual = new groovy.json.JsonSlurper().parse(prev.getResponseData())
if (expected != actual) {
AssertionResult.setFailure(true)
AssertionResult.setFailureMessage('Mismatch between expected and actual JSON')
}
just with this I'm not able to validate the dynamic "id" field
any idea?
Thanks in advance
If you're not interested in this id field - just remove it from the expected variable and the actual response, to wit amend first 2 lines of your assertion to look like:
def expected = new groovy.json.JsonSlurper().parseText(vars.get('expected1')).each {entry -> entry.remove('id')}
def actual = new groovy.json.JsonSlurper().parse(prev.getResponseData()).each {entry -> entry.remove('id')}
More information:
Groovy: Parsing and Producing JSON
Apache Groovy - Why and How You Should Use It
Demo:
If value is not your concern for id field you can directly use regex matcher to check the field using Jsonassertion by specifying jsonpath and check match as regex use regex

Comparing Json data. Python 3

I have the following Json file and I need to compare data to see how many times each value repeat itself. The problem is, I have no idea about handling Json. I don't want the answer to my exercise, I want to know how to access the data. Json:
{
"tickets": [
{
"ticket_id": 0,
"timestamp": "2016/05/26 04:47:02",
"file_hash": "c9d4e03c5632416f",
"src_ip": "6.19.128.119",
"dst_ip": "145.231.76.44"
},
{
"ticket_id": 1,
"timestamp": "2017/05/28 16:14:22",
"file_hash": "ce8a056490a3fd3c",
"src_ip": "100.139.125.30",
"dst_ip": "145.231.76.44"
},
{
"ticket_id": 2,
"timestamp": "2015/08/23 03:27:10",
"file_hash": "d17f572496f48a11",
"src_ip": "67.153.41.75",
"dst_ip": "239.168.56.243"
},
{
"ticket_id": 3,
"timestamp": "2016/02/26 14:01:33",
"file_hash": "3b28f2abc966a386",
"src_ip": "6.19.128.119",
"dst_ip": "137.164.166.84"
},
]
}
If this is a string representation of the object, first you need to set a variable and parse the string to have object you can work with.
jsonString = "{...your json string...}"
Then parse the string,
import json
jsonObject = json.loads(jsonString)
To access the data within it's like any other js object. Example :
jsonObject.tickets[0].timestamp
would return "2016/05/26 04:47:02"
tickets is the key within the jsonObject, 0 is the index of the first object in the list of tickets.
You can use the built-in "json" library to parse your file into an object:
import json
f = open('myfile.json','r')
tickets = json.loads(f.read())
This will return a "tickets" object. How you "compare" (or what exactly you compare) is up to you.

How can I extract fields from JSON only when three matching fields are present?

I want to extract employeid and result where deptcode, Name, and position are present.
{
"employeeid": 101,
"result": {
"deptcode": 0,
"Name": "Henry",
"position": "Administrator head."
}
}
My current code is:
i = beginIndex
temp = ""
value = ""
while i < endIndex
temp = dataMap[i].to_s.split(":")[1].strip()
value += "#{temp},"
i += 1
end
Extract Fields by Hash Key
If you have a valid JSON string, you can covert it to a Ruby hash and access fields by key. Using Enumerable#all? will enable you to only return a value if all fields are present. For example:
require 'json'
# Use a valid JSON string, or a native Ruby hash. We'll assume you're
# starting with a JSON string, although the following would be a valid
# Ruby hash object without parsing if not wrapped in quotes. YMMV.
json = <<~EOF
{
"employeeid": 101,
"result": {
"deptcode": 0,
"Name": "Henry",
"position": "Administrator head."
}
}
EOF
# Convert the JSON above to a Ruby hash.
hash = JSON.parse json
# Extract fields when all keys are present.
[ hash['employeeid'], hash['result'] ] if
hash['result'].keys.all? { |key| %w[deptcode Name position].include? key }
#=> [101, {"deptcode"=>0, "Name"=>"Henry", "position"=>"Administrator head."}]
This works fine with your corrected corpus. If you have an array of results, or a deeply-nested structure, then you'll need to do some additional coding to make it work. However, it works just fine with the refactored data given in the original post.

SOAP UI Assertion Help : To validate Total attribute and Total Value

I searched in Google and Stackoverflow and I didn't find any helpful information and decide to post question.
I am getting response from API in JSON.
{
"CouponCode": [{
"id": 56,
"name": "BlackFriday"
}, {
"id": 58,
"name": "ThanksGiving"
}, {
"id": 62,
"name": "New Year"
}]}
I need to add assertion that will count that there are total 3 id and 3 name.
All IDs and Names are not empty. We don't want to send empty attribute value.
I am using SOAP UI open source. Please provide exact code or exact reference.
Exactly assertion needs to
Find total Ids and Name that's will be size
Find total Ids and Name size.
If Id is 3 and 3 Ids value are three..if JSON come like in this case assertion will failed.
this
{
"CouponCode": [{
"id": 56,
"name": "BlackFriday"
}, {
"id": 58,
"name": "ThanksGiving"
}, {
"id": "",
"name": "New Year"
}]}
The below groovy script uses json way to check the expected results.
Add the groovy script step after the rest request step in your test case.
Sudo code for extracting the same.
Read the json text. If you do not want to use fixed response, read it from previous step response. Create the object.
Make sure you have the expected counts for id, and name. You may also define them at test case custom properties in case do not want to use fixed values and change each time in the script.
find all the id count and check with expected value and show the error message in case of failure.
Similar to step 3, do the assert for names.
//for testing using fixed response, you may aslo assign dynamic response.
def jsonText = '''
{
"CouponCode": [{
"id": 56,
"name": "BlackFriday"
}, {
"id": 58,
"name": "ThanksGiving"
}, {
"id": 62,
"name": "New Year"
}]}'''
def coupons = new groovy.json.JsonSlurper().parseText(jsonText).CouponCode
//You may also read these values from test case properties
def expectedIdCount = 3
def expectedNameCount = 3
//assert the expected id count with find all coupon ids count of json response
assert expectedIdCount == coupons.findAll{it.id}.size(), "Coupon id count does not match"
//assert the expected name count with find all coupon names count of json response
assert expectedNameCount == coupons.findAll{it.name}.size(), "Coupon name count does not match"
The same can be achieved using script assertion for the rest step as well, that will avoid additional groovy script step. But it may require little changes in the script as below.
How to read the json response dynamically?
From script assertion
Use below line and remove the fixed jsonText from above.
def jsonText = messageExchange.response.responseContent
From Groovy script step
//replace the rest request step name below
def jsonText = context.expand('${ReplaceStepName#Response}')
How to read the test case level properties for expected results instead of hardcoded values in the script?
Define a test case level property for id, say EXPECTED_ID_COUNT and provide value 3 like you mentioned and similarly, define for name as well.
//read in script these properties
def expectedIdCount = context.testCase.getPropertyValue('EXPECTED_ID_COUNT') as Integer
There are several possible solutions. The easiest is to use an XPath assertion; keep in mind that internally, SoapUI converts everything to XML if it can.
count(//*:id)
expected result:
3
Similarly for your name.