web-dev-qa-db-ja.com

Ruby on RailsでJSONを解析する方法

私はJSONを解析し、値を抽出してRailsのデータベースに書き込むための簡単な方法を探しています。

特に私が探しているのは、bit.ly APIから返されたJSONからshortUrlを抽出する方法です。

{
  "errorCode": 0,
  "errorMessage": "",
  "results":
  {
    "http://www.foo.com":
    {
       "hash": "e5TEd",
       "shortKeywordUrl": "",
       "shortUrl": "http://bit.ly/1a0p8G",
       "userHash": "1a0p8G"
    }
  },
  "statusCode": "OK"
}

そしてそのshortUrlを取得して、それを長いURLに関連付けられたActiveRecordオブジェクトに書き込みます。

これは私が完全に概念的に考えることができるそれらのうちの1つであり、私が実行するために座るとき私は私が学ぶべきことがたくさんあることに気づく。

306
Dan Sinker

これらの答えは少し古くなっています。だから私はあなたにあげる:

hash = JSON.parse string

Railsは自動的にjsonモジュールを自動的にロードしますので、require 'json'を追加する必要はありません必要はありません

438
pguardiario

RailsでJSONを解析するのはとても簡単です。

parsed_json = ActiveSupport::JSON.decode(your_json_string)

ShortUrlを関連付けるオブジェクトがSiteオブジェクトで、2つの属性(short_urlとlong_url)があるとします。それよりも、shortUrlを取得してそれを適切なSiteオブジェクトに関連付けるには、次のようにします。

parsed_json["results"].each do |longUrl, convertedUrl|
  site = Site.find_by_long_url(longUrl)
  site.short_url = convertedUrl["shortUrl"]
  site.save
end
184
Milan Novota

この答えはかなり古いです。 pguardiarioはそれを持っています。

チェックアウトする1つのサイトは、 Ruby用のJSON実装です 。このサイトはあなたがはるかに速いC拡張の変種のためにインストールすることができる宝石を提供します。

彼らの ドキュメントページ に与えられたベンチマークで彼らはそれがActiveSupport::JSON.decodeよりも21.500x速いと主張します

コードは、この宝石に関するMilan Novotaの答えと同じですが、解析は以下のようになります。

parsed_json = JSON(your_json_string)
56
lillq

これは2013年の更新です。

ルビー

Ruby 1.9にはデフォルトの JSON gem とC拡張があります。あなたはそれを使用することができます

require 'json'
JSON.parse ''{ "x": "y" }'
# => {"x"=>"y"}

parse!バリアントは、安全なソースに使用できます。他のgemもあります。これはデフォルトの実装より速いかもしれません。リストについては multi_json を参照してください。

レール

最新バージョンのRailsは multi_json を使用します。これは、利用可能な最も速いJSON gemを自動的に使用するgemです。したがって、推奨される方法は使用することです

object = ActiveSupport::JSON.decode json_string

詳しくは ActiveSupport :: JSON を参照してください。特に、メソッドソースの重要な行は

data = MultiJson.load(json, options)

それからあなたのGemfileに、あなたが使いたいgemを含めてください。例えば、

group :production do
  gem 'oj'
end
19
James Lim

Rubyのバンドル版 JSON は、それ自体でちょっとした魔法を見せることができます。

解析したいJSONシリアライズデータを含む文字列がある場合:

JSON[string_to_parse]

JSONはパラメータを調べ、それが文字列であることを確認し、それをデコードしてみます。

同様に、シリアル化したいハッシュまたは配列がある場合は、次のようにします。

JSON[array_of_values]

または

JSON[hash_of_values]

そしてJSONはそれをシリアライズします。 to_jsonメソッド の視覚的類似性を避けたい場合は、 [] メソッドも使用できます。

ここではいくつかの例を示します。

hash_of_values = {'foo' => 1, 'bar' => 2}
array_of_values = [hash_of_values]

JSON[hash_of_values] 
# => "{\"foo\":1,\"bar\":2}"

JSON[array_of_values] 
# => "[{\"foo\":1,\"bar\":2}]"

string_to_parse = array_of_values.to_json
JSON[string_to_parse]
# => [{"foo"=>1, "bar"=>2}]

もしあなたがJSONに根ざしているなら、それがYAMLのサブセットであることに気づくかもしれません、そして、実際には、YAMLパーサはJSONを扱っているものです。これもできます。

require 'yaml'

YAML.load(string_to_parse)
# => [{"foo"=>1, "bar"=>2}]

アプリケーションがYAMLとJSONの両方を解析している場合は、YAMLに両方の種類のシリアル化データを処理させることができます。

7
the Tin Man
require 'json'
out=JSON.parse(input)

これはハッシュを返します

5
user2726667
require 'json'

hash = JSON.parse string

ハッシュを操作して、やりたいことをします。

これは以下のように行うことができます。単にJSON.parseを使用する必要があります、それからあなたはそれをインデックスで通常通り抜けることができます。

#ideally not really needed, but in case if JSON.parse is not identifiable in your module  
require 'json'

#Assuming data from bitly api is stored in json_data here

json_data = '{
  "errorCode": 0,
  "errorMessage": "",
  "results":
  {
    "http://www.foo.com":
    {
       "hash": "e5TEd",
       "shortKeywordUrl": "",
       "shortUrl": "http://whateverurl",
       "userHash": "1a0p8G"
    }
  },
  "statusCode": "OK"
}'

final_data = JSON.parse(json_data)
puts final_data["results"]["http://www.foo.com"]["shortUrl"]
2
Nishant Rawat

これが私のやり方です。

json = "{\"errorCode\":0,\"errorMessage\":\"\",\"results\":{\"http://www.foo.com\":{\"hash\":\"e5TEd\",\"shortKeywordUrl\":\"\",\"shortUrl\":\"http://b.i.t.ly/1a0p8G\",\"userHash\":\"1a0p8G\"}},\"statusCode\":\"OK\"}"

hash = JSON.parse(json)
results = hash[:results]

あなたがソースURLを知っているなら、あなたはそれを使うことができます:

source_url = "http://www.foo.com".to_sym

results.fetch(source_url)[:shortUrl]
=> "http://b.i.t.ly/1a0p8G"

ソースURLのキーがわからない場合は、次の操作を行います。

results.fetch(results.keys[0])[:shortUrl]
=> "http://b.i.t.ly/1a0p8G"

シンボルを使用してキーを検索したくない場合は、ハッシュ内のキーを文字列に変換できます。

results = json[:results].stringify_keys

results.fetch(results.keys[0])["shortUrl"]
=> "http://b.i.t.ly/1a0p8G"

JSON構造が変わる可能性があるのであれば、単純なJSONスキーマを作成してキーにアクセスする前にJSONを検証することができます。これはガードを提供します。

注:投稿ルールのため、bit.lyのURLを変更する必要がありました。

2
Jurgen

Rubyは大文字と小文字を区別します。

require 'json' # json must be lower case

JSON.parse(<json object>)  

例えば

JSON.parse(response.body) # JSON must be all upper-case
2
Steven

Oj gem( https://github.com/ohler55/oj )が動作するはずです。それはシンプルで速いです。

http://www.ohler.com/oj/#Simple_JSON_Writing_and_Parsing_Example

require 'oj'

h = { 'one' => 1, 'array' => [ true, false ] }
json = Oj.dump(h)

# json =
# {
#   "one":1,
#   "array":[
#     true,
#     false
#   ]
# }

h2 = Oj.load(json)
puts "Same? #{h == h2}"
# true

Oj gemはJRubyでは動きません。 JRubyの場合はこちら( https://github.com/ralfstx/minimal-json )またはこちら( https: //github.com/clojure/data.json )が良い選択肢かもしれません。

2
John Moore