2

I want to break down a JSON string into smaller objects. I have two servers, one acting as the web-app interface to the whole application and the other is a repository/database.

I'm able to retrieve information from the repository to the web-app as JSON, but after that I don't know how to return it.

Here's a sample of the JSON being returned:

{"respPages":[{"page":{"page_url":"http://www.google.com/","created_at":"2011-08-10T11:00:19Z","website_id":1,"updated_at":"2011-08-10T11:00:19Z","id":1}},{"page":{"page_url":"http://www.blank.com/services/content_services/","created_at":"2011-08-10T11:02:46Z","website_id":1,"updated_at":"2011-08-10T11:02:46Z","id":2}}],"respSite":{"website":{"created_at":"2011-08-10T11:00:19Z","website_id":null,"updated_at":"2011-08-10T11:00:19Z","website_url":null,"id":1}},"respElementTypes":[{"element_type":{"created_at":"2011-08-10T11:00:19Z","updated_at":"2011-08-10T11:00:19Z","id":1,"tag_name":"head"}},

There are four tags in the JSON:

page
website
elementType
elementData

I would like to create four arrays and populate them with the object that matches these tags.

I would image the code is something like this:

#Get the json from repo using net/http
 uri = URI.parse("http://127.0.0.1:3007/repository/infoid/1.json")
 http = Net::HTTP.new(uri.host, uri.port)
 response = http.request(Net::HTTP::Get.new(uri.request_uri))


@x = response.to_hash

@pages = Array.new
@websites= Array.new
@elementDatas = Array.new
@elementTypes = Array.new

#enter code here`#For every bit of the hash, find out what it is and allocate it accordingly
    @x.each_with_index do |e,index|
    if e.tagName == pages #Getting real javascripty here. There must be someway to check the tag or title of the element
    @pages[index]=e
    end

My goal for the returned value is to have four arrays, each containing different types of objects:

  @pagesArray[1]

should contain the first occurrence of a page object in the JSON string. Then do the same for the other ones.

Of course I'd need to break down the object further but once I can break down the top level and categorize them, then I can go deeper.

In the JSON there are already tag titles respPages and respWebsites which group all the objects.

How do I turn JSON back into objects in Ruby and reference them using something like the tag name?

4
  • I don't understand: you want the json string to be transformed into an object? If so: ActiveSupport::JSON.decode(string) Commented Aug 10, 2011 at 15:17
  • Not quite. I want to identify objects within the json string. The string is multiple objects combined, not singular Commented Aug 10, 2011 at 15:19
  • give a detailed example of your expected output Commented Aug 10, 2011 at 15:21
  • @apeneadiving. 4 arrays full of objects as determined by the json string is the short answer. Edited question Commented Aug 10, 2011 at 15:26

2 Answers 2

3

You should be able to decode anything in JSON format using the standard JSON library:

JSON.load(...)

It will throw exceptions on malformed JSON data, so be sure to test it thoroughly and make sure it can handle all the important cases.

If you're trying to navigate the structure of the JSON itself, you probably need to write a series of recursive methods that handle each case along the way. A good pattern to start with is this:

@data.each do |key, value|
  case (key)
  when 'someKey'
    handle_some_key(value)
  when 'otherKey'
    handle_other_key(value)
  end
end

You can either break out the behavior into methods as in this example, or inline it if the logic is fairly straightforward.

As a note, an alternative to Array.new is simply [ ] as it is in JavaScript. For example:

@pages = [ ]

You'll see this used frequently in most Ruby examples. The alternative to Hash.new is { }.

Sign up to request clarification or add additional context in comments.

7 Comments

The key part is the bit im having trouble with. I don't know how to compare a specific part of the json with a plain string. Javascript short would by document.getElementById() or get by xpath. Is there any way to compare it? p.s thanks for the note on the arrays
@OVERTONE: "thanks" is generally traduced with +1 on stackoverflow :)
Ok so theres just 2 parts to this i don't understand. @data would have to be an array or hash for it to use the .each method. But I have no idea how to deserialize the json into one of these. Second is kind of dependent on 1. if theres no way to get data then theres no way to compare the keys. So short recap, how do i turn the JSON into an array or hash that I can cycle through?
Maybe I'm missing something, but the JSON example you provided has both hashes and arrays in it. There's also something missing, probably because it was truncated.
@tadman, It was truncated yes. there was a lot of text and I felt it would take up too much screen space. But the general of it is there. respPages is an array of hashes. page is a hash with keys and information. I basically want to grab those arrays and hashes out of the object but don't know how. using Json.PARSE or DECODE returns a string and a YAML dump prints the objects as they are. But i dont know how to reference them. Like at all.Shoul I repost the question with a bit clearer messaging?
|
0

The following works:

json = {"respPages"=>[{"page"=>{"page_url"=>"http://www.google.com", "created_at"=>"2011-08-10T11:00:19Z", "website_id"=>1, "updated_at"=>"2011-08-10T11:00:19Z", "id"=>1}}, {"page"=>{"page_url"=>"http://www.blank.com/services/content_services/", "created_at"=>"2011-08-10T11:02:46Z", "website_id"=>1, "updated_at"=>"2011-08-10T11:02:46Z", "id"=>2}}], 
        "respSite"=>{"website"=>{"created_at"=>"2011-08-10T11:00:19Z", "website_id"=>nil, "updated_at"=>"2011-08-10T11:00:19Z", "website_url"=>nil, "id"=>1}}, 
        "respElementTypes"=>[{"element_type"=>{"created_at"=>"2011-08-10T11:00:19Z", "updated_at"=>"2011-08-10T11:00:19Z", "id"=>1, "tag_name"=>"head"}}]}

@respPages, @respSite, @respElementTypes = [], [], []

json.each do |key_category, group_category|
  group_category.each do |hash|
    if group_category.is_a? Array
      eval("@#{key_category}") << hash.values.first
    elsif group_category.is_a? Hash
      eval("@#{key_category}") << hash[1]
    end
  end
end

there weren't any respData in your sample but you've got the idea.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.