runski74 runski74 - 1 year ago 105
JSON Question

Ruby Parsing json array with OpenStruct

I'm trying to parse a json file with OpenStruct. Json file has an array for Skills. When I parse it I get some extra "garbage" returned. How do I get rid of it?


"Job": "My Job 1",

"Skills": [{ "Name": "Name 1", "ClusterName": "Cluster Name 1 Skills"},{ "Name": "Name 2", "ClusterName": "Cluster Name 2 Skills"}]

require 'ostruct'
require 'json'

json ='1.json')
job = JSON.parse(json, object_class: OpenStruct)

puts job.Skills

#<OpenStruct Name="Name 1", ClusterName="Cluster Name 1 Skills">
#<OpenStruct Name="Name 2", ClusterName="Cluster Name 2 Skills">

Answer Source

If by garbage, you mean #<OpenStruct and ">, it is just the way Ruby represents objects when called with puts. It is useful for development and debugging, and it makes it easier to understand the difference between a String, an Array, an Hash and an OpenStruct.

If you just want to display the name and cluster name, and nothing else :

puts job.Job
job.Skills.each do |skill|
  puts skill.Name
  puts skill.ClusterName

It returns :

My Job 1
Name 1
Cluster Name 1 Skills
Name 2
Cluster Name 2 Skills


When you use job = JSON.parse(json, object_class: OpenStruct), your job variable becomes an OpenStruct Ruby object, which has been created from a json file.

It doesn't have anything to do with json though: it is not a json object anymore, so you cannot just write it back to a .json file and expect it to have the correct syntax.

OpenStruct doesn't seem to work well with to_json, so it might be better to remove object_class: OpenStruct, and just work with hashes and arrays.

This code reads 1.json, convert it to a Ruby object, adds a skill, modifies the job name, writes the object to 2.json, and reads it again as JSON to check that everything worked fine.

require 'json'

json ='1.json')
job = JSON.parse(json)

job["Skills"] << {"Name" => "Name 3", "ClusterName" => "Cluster Name 3 Skills"}
job["Job"] += " (modified version)"

# job[:Fa] = 'blah''2.json', 'w'){|out|
  out.puts job.to_json

require 'pp'
pp JSON.parse('2.json'))

# {"Job"=>"My Job 1 (modified version)",
# "Skills"=>
#  [{"Name"=>"Name 1", "ClusterName"=>"Cluster Name 1 Skills"},
#   {"Name"=>"Name 2", "ClusterName"=>"Cluster Name 2 Skills"},
#   {"Name"=>"Name 3", "ClusterName"=>"Cluster Name 3 Skills"}]}