extracting nested values from JSON using Ruby - json

I want to extract the individual values by key out of this JSON.
json = JSON.parse({ "streams": [ { "index": 0, "codec_name": "mpeg2video"} ] })
Using json['streams'].each do |codec_name| returns the whole first array back. I also tried identifying specific array number by json['streams'][1].each do |codec_name| and that errors.
Final output should return "mpeg2video"?

This is what worked. Had to drill down through the Array and Hash to get to it.
((json[''].each { |j| j['streams'] })[0])["codec_name"]

Since you appear to have an array of hashes in your JSON, you need to target the key codec_name. This should work:
# Assuming json_hash is a Hash that was returned by `JSON.parse()`
json_hash = { "streams": [ { "index": 0, "codec_name": "mpeg2video"} ] }
json_hash['streams'].each { |j| j['codec_name'] }
In this loop j is targeting the hash, and therefore you need j['codec_name']

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"

Using parsed json by JsonSlurper, how do I return a value based on another key value pair of the same node?

I have below JSON and want to fetch the value of "person1" and "person2" either into a map as a key-value pair or individually is also fine.
Expected Output: [attributes:["person1": "ROBERT", "person2": "STEVEN"]]
I started with JSON parsing and dont really have idea on what to do next?
def parsedJSON= new groovy.json.JsonSlurper().parseText(body)
JSON
"permutationsRequest":{
"attributes":[
{
"name":"person1",
"value":"ROBERT"
},
{
"name":"person2",
"value":"STEVEN"
}
]
}
}
def map = parsedJSON.permutationsRequest.attributes.collectEntries{ [it.name,it.value] }
println map.person2

nested JSON ruby extract values

I want to extract the individual values by key out of this JSON.
json = JSON.parse({ "streams": [ { "index": 0, "codec_name": "mpeg2video"} ] })
Using json['streams'].each do |codec_name| returns the whole first array back. I also tried identifying specific array number by json['streams'][0].each do |codec_name| and that errors.
The output expected should be "mpeg2video"

Stream analytics parse json, same key can be array or not

A XML is converted to JSON and sent to an EventHub and then a Stream Analytics process it.
The problem is when XML uses the same tags name it gets converted to a list on the JSON side, but when there is only one tag is not converted to a list. So the same tag can be an array or not.
Ex:
I can receive either:
{
"k1": 123,
"k2": {
"l1": 2,
"l2": 12
}
}
or:
{
"k1": 123,
"k2": [
{
"l1": 2,
"l2": 12
},
{
"l1": 3,
"l2": 34
}
]
}
I can easily deal with the first scenario and the second scenario independently, but I don't know how to deal with both at the same time, is this possible?
Yes, it is. If you know how to deal with each of the cases individually, I will just suggest an idea of how you can make the distinction between these two cases, before you treat them individually.
Essentially, the idea is to check if the field is an array. What I did was, I wrote a UDF function in javascript that returns "true"/"false", if the passed object is an array:
function UDFSample(arg1) {
'use strict';
var isArray = Array.isArray(arg1);
return isArray.toString();
}
here is how you can use this in the group query:
with test as (SELECT Document from input where UDF.IsArray(k2) = 'true')
now "test" contains items that you can treat as an array. The same you can do for the case where k2 is just an object.

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.