The examination of a JSON document utilizing Ruby: A 
     Step-by-Step Guide
Tags: ruby, json
Published: 2020-12-14 00:07:43

A person could have learned how to work with nested hashes and yet still find a JSON file to be overwhelming. A JSON file does not only contain multiple layers of nested hashes but can also contain arrays nested sporadically among the hashes. The following are the steps that can be taken to examine the JSON document in an organized manner.

               Step 1: Open your file.

In this overview an API to a JSON file will be utilized so that the reader can code along before moving on to a different JSON file. Obviously, the manner in which a file is opened will be determined by the exact location of the file. The code of binding.pry has been inserted so that the file can be examined in the terminal utilizing pry. Don’t forget to call the method in the file after creating it:

require 'net/http'
require 'open-uri'
require 'json'
require 'pry'

 

  URL = "https://health.gov/myhealthfinder/api/v3/topicsearch.json?lang=en"

  def get_info
    uri = URI.parse(URL)
    response = Net::HTTP.get_response(uri)
    response.body
   
  
  end
 

file = get_info
binding.pry


The following will appear in your terminal after running the file:

david@LT000568:~/projects/health-information-site$ ruby lib/test.rb
/home/david/.rvm/gems/ruby-2.6.1/gems/pry-0.13.1/lib/pry/editor.rb:19: warning: Insecure world writable dir /mnt/c in PATH, mode 040777

From: /home/david/projects/health-information-site/lib/test.rb:20 :

    15:   
    16:   end
    17:  
    18: 
    19: file = get_info
 => 20: binding.pry


          Step 2: Determine the length of the file.

Note that all entries from now on are being done in the terminal which is open to pry. Remember that if necessary, the letter q should be entered to be ready for the next entry. file.length gives us the size of the file.

[1] pry(main)> file.length
=> 1332586
[2] pry(main)> 

                 Step 3: Parse the file.

One can examine more of the file by pressing on the down arrow as many times as one wants so examine as much of the file as is desired.  
[2] pry(main)> data = JSON.parse(file)
=> {"Result"=>
  {"Error"=>"False",
   "Total"=>98,
   "Query"=>
    {"ApiVersion"=>"3",
     "ApiType"=>"topicsearch",
     "TopicId"=>nil,
     "ToolId"=>nil,
     "CategoryId"=>nil,
     "PopulationId"=>nil,
     "Keyword"=>nil,
     "Who"=>nil,
     "Age"=>nil,
     "Sex"=>nil,
     "Pregnant"=>nil,
     "TobaccoUse"=>nil,
     "SexuallyActive"=>nil,
     "Category"=>nil,
     "Lang"=>"en",
     "Type"=>nil,
     "ReturnType"=>"json",
     "Callback"=>nil,
[3] pry(main)>

        Step 4: Determine the type of the overall file.

We will now use the .class method to confirm the type of the overall file. It is important to note that the “file” variable which is before the parsing is a string while the “data” variable which is after the parsing and which is what we are working with is a hash.

[3] pry(main)> data.class
=> Hash

            Step 5: Since this is a hash, use the .keys method 
                      to find the first one.

This step could really be skipped since the first key was revealed in step 3. It is just being mentioned because it is a simple starting point for what can be an overwhelming amount of data.

[4] pry(main)> data.keys
=> ["Result"]

            Step 6: Scroll down to find where the desired 
                     information is located.

Here entering “data”, one can scroll using the down arrow to the first line of desired information. In this case it was "Keep Your Heart Healthy".

[5] pry(main)> data
=> {"Result"=>
  {"Error"=>"False",
   "Total"=>98,
   "Query"=>
    {"ApiVersion"=>"3",
     "ApiType"=>"topicsearch",
     "TopicId"=>nil,
     "ToolId"=>nil,
     "CategoryId"=>nil,
     "PopulationId"=>nil,
     "Keyword"=>nil,
     "Who"=>nil,
     "Age"=>nil,
     "Sex"=>nil,
     "Pregnant"=>nil,
     "TobaccoUse"=>nil,
     "SexuallyActive"=>nil,
     "Category"=>nil,
     "Lang"=>"en",
     "Type"=>nil,
     "ReturnType"=>"json",
     "Callback"=>nil,
     "HealthfinderPage"=>nil,
     "APiType"=>"topicsearch"},
   "Language"=>"English",
   "Resources"=>
    {"Resource"=>
      [{"Type"=>"Topic",
        "Id"=>"25",
        "Title"=>"Keep Your Heart Healthy",
        "TranslationId"=>"25",
[6] pry(main)>

       Step 7: Start listing the keys necessary to reach the 
                       information. 

One can see that there is a first key “Result” and that the desired line is arrived at by going to the key called “Resources” followed by the key called “Resource.” We can now consecutively enter a key and using the .keys method choose which of its contained keys we want to use. Note that the "Resources" key only has one key following it and that is "Resource". When we encounter a non-hash such as an array, the .keys method will generate a NoMethodError.  

[6] pry(main)> data["Result"].keys
=> ["Error", "Total", "Query", "Language", "Resources"]
[7] pry(main)> data["Result"]["Resources"].keys
=> ["Resource"]
[8] pry(main)> data["Result"]["Resources"]["Resource"].keys
NoMethodError: undefined method `keys' for #<Array:0x00007fffc58bdcc0>
[9] pry(main)>
 
              Step 8: At the array, use indexing to find the 
                         desired information.

 As we saw in step 6, the desired line is in the first hash within the array so this would be index 0. We will now examine the keys of that first hash in the array.
[9] pry(main)> data["Result"]["Resources"]["Resource"][0].keys
=> ["Type",
 "Id",
 "Title",
 "TranslationId",
 "TranslationTitle",
 "Categories",
 "Populations",
 "MyHFTitle",
 "MyHFDescription",
 "MyHFCategory",
 "MyHFCategoryHeading",
 "LastUpdate",
 "ImageUrl",
 "ImageAlt",
 "AccessibleVersion",
 "RelatedItems",
 "Sections",
 "MoreInfoItems",
 "HealthfinderLogo",
 "HealthfinderUrl"]
[10] pry(main)>

          Step 9: Arriving at the desired information.

As seen in step 6, the desired line is the value for the “Title” key, so using it will allow us to arrive at the desired line.

[10] pry(main)> data["Result"]["Resources"]["Resource"][0]["Title"]
=> "Keep Your Heart Healthy"

             Step 10: Continue in the same manner until all 
                     information is obtained.

Just continue repeating the above steps until you have collected all the desired information. In my case the next desired information was not near the first piece, so it took several keys and indices to arrive at it.

[11] pry(main)>data["Result"]["Resources"]["Resource"][1]["Sections"]
["section"][0]["Title"]
=> "The Basics: Overview"
[12] pry(main)>

I hope that you found this posting to be helpful. Please let me know if you have any comments.