从JSON字符串中提取JSON对象

时间:2011-08-10 15:10:25

标签: ruby-on-rails ruby json object hash

我想将JSON字符串分解为较小的对象。我有两台服务器,一台作为整个应用程序的web-app接口,另一台是存储库/数据库。

我能够将信息从存储库检索到网络应用程序作为JSON,但之后我不知道如何返回它。

以下是返回的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":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"}},

JSON中有四个标签:

page
website
elementType
elementData

我想创建四个数组,并用匹配这些标记的对象填充它们。

我会想象代码是这样的:

#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

我返回值的目标是有四个数组,每个数组包含不同类型的对象:

  @pagesArray[1]

应包含JSON字符串中第一次出现的页面对象。然后对其他人做同样的事情。

当然我需要进一步细分对象,但是一旦我可以分解顶层并对它们进行分类,那么我可以更深入。

在JSON中,已经有标记标题respPagesrespWebsites,它们对所有对象进行分组。

如何将JSON重新转换为Ruby中的对象,并使用标记名称等引用它们?

2 个答案:

答案 0 :(得分:3)

您应该能够使用标准JSON库解码JSON格式的任何内容:

JSON.load(...)

它将在格式错误的JSON数据上抛出异常,因此请务必对其进行彻底测试,并确保它能够处理所有重要案例。

如果您正在尝试导航JSON本身的结构,您可能需要编写一系列递归方法来处理每个案例。一个好的模式是:

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

您可以将行为分解为方法,如本示例所示,或者如果逻辑非常简单,则将其内联。

作为备注,Array.new的替代方案只是[ ],就像在JavaScript中一样。例如:

@pages = [ ]

在大多数Ruby示例中,您会经常看到这种情况。 Hash.new的替代方法是{ }

答案 1 :(得分:0)

以下作品:

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

您的样本中没有respData,但您已经明白了。