wake-up-neo.com

Wie analysiere ich JSON mit Ruby on Rails?

Ich suche nach einer einfachen Möglichkeit, JSON zu analysieren, einen Wert zu extrahieren und in Rails in eine Datenbank zu schreiben.

Insbesondere suche ich nach einer Möglichkeit, shortUrl aus dem von der bit.ly-API zurückgegebenen JSON zu extrahieren:

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

Nehmen Sie dann diese shortUrl und schreiben Sie sie in ein ActiveRecord-Objekt, das der langen URL zugeordnet ist.

Dies ist eines der Dinge, die ich ganz im Konzept durchdenken kann, und wenn ich mich hinsetze, um sie auszuführen, stelle ich fest, dass ich viel lernen muss.

308
Dan Sinker

Diese Antworten sind etwas veraltet. Deshalb gebe ich dir:

hash = JSON.parse string

Rails sollte das json -Modul automatisch für Sie laden, sodass Sie nichtrequire 'json' Hinzufügen müssen.

442
pguardiario

Das Parsen von JSON in Rails ist ganz einfach:

parsed_json = ActiveSupport::JSON.decode(your_json_string)

Angenommen, das Objekt, dem Sie die shortUrl zuordnen möchten, ist ein Site-Objekt mit zwei Attributen - short_url und long_url. Um die shortUrl abzurufen und mit dem entsprechenden Site-Objekt zu verknüpfen, können Sie Folgendes tun:

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

Diese Antwort ist ziemlich alt. pguardiario hat es verstanden.

Eine Seite, die Sie auschecken sollten, ist JSON-Implementierung für Ruby . Diese Seite bietet ein Juwel, das Sie für eine viel schnellere C-Erweiterungsvariante installieren können.

Mit den Benchmarks als Dokumentationsseite behaupten sie, dass es 21.500x schneller ist als ActiveSupport::JSON.decode

Der Code wäre derselbe wie die Antwort von Milan Novota mit diesem Juwel, aber das Parsen wäre einfach:

parsed_json = JSON(your_json_string)
56
lillq

Hier ist ein Update für 2013.

Ruby

Ruby 1.9 hat eine Standardeinstellung JSON-Gem mit C-Erweiterungen. Sie können es mit verwenden

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

Das parse! variant kann für sichere Quellen verwendet werden. Es gibt auch andere Juwelen, die möglicherweise schneller als die Standardimplementierung sind. Die Liste finden Sie unter multi_json .

Rails

Moderne Versionen von Rails use multi_json , einem Juwel, das automatisch das schnellste verfügbare JSON-Juwel verwendet. Daher wird die Verwendung empfohlen

object = ActiveSupport::JSON.decode json_string

Weitere Informationen finden Sie unter ActiveSupport :: JSON . Insbesondere ist die wichtige Zeile in der Methodenquelle

data = MultiJson.load(json, options)

Fügen Sie dann in Ihre Gemdatei die Edelsteine ​​ein, die Sie verwenden möchten. Zum Beispiel,

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

Rubys gebündeltes JSON ist in der Lage, selbst ein bisschen Magie zu entfalten.

Wenn Sie eine Zeichenfolge mit JSON-serialisierten Daten haben, die Sie analysieren möchten:

JSON[string_to_parse]

JSON überprüft den Parameter, ob es sich um einen String handelt, und versucht, ihn zu dekodieren.

Wenn Sie über einen Hash oder ein Array verfügen, das serialisiert werden soll, verwenden Sie Folgendes:

JSON[array_of_values]

Oder:

JSON[hash_of_values]

Und JSON wird es serialisieren. Sie können auch die to_json Methode, wenn Sie die visuelle Ähnlichkeit der [] Methode .

Hier sind einige Beispiele:

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}]

Wenn Sie in JSON herumwühlen, stellen Sie möglicherweise fest, dass es sich um eine Teilmenge von YAML handelt, und tatsächlich ist der YAML-Parser das, was JSON behandelt. Sie können dies auch tun:

require 'yaml'

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

Wenn Ihre App sowohl YAML als auch JSON analysiert, können Sie YAML beide Arten von serialisierten Daten verarbeiten lassen.

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

Dies gibt einen Hash zurück

5
user2726667
require 'json'

hash = JSON.parse string

arbeite mit dem Hash und mach was du willst.

Dies kann wie folgt durchgeführt werden, muss nur JSON.parse, dann können Sie es normal mit Indizes durchlaufen.

#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"]
3
Nishant Rawat

Folgendes würde ich tun:

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]

Wenn Sie die Quell-URL kennen, können Sie Folgendes verwenden:

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

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

Wenn Sie den Schlüssel für die Quell-URL nicht kennen, können Sie Folgendes tun:

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

Wenn Sie Schlüssel nicht mit Symbolen suchen möchten, können Sie die Schlüssel im Hash in Zeichenfolgen konvertieren:

results = json[:results].stringify_keys

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

Wenn Sie befürchten, dass sich die JSON-Struktur ändert, können Sie ein einfaches JSON-Schema erstellen und das JSON validieren, bevor Sie versuchen, auf Schlüssel zuzugreifen. Dies würde eine Wache bieten.

HINWEIS: Die bit.ly-URL musste aufgrund von Veröffentlichungsregeln entstellt werden.

2
Jurgen

Ruby unterscheidet zwischen Groß- und Kleinschreibung.

require 'json' # json must be lower case

JSON.parse(<json object>)  

zum Beispiel

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

Das Oj-Juwel ( https://github.com/ohler55/oj ) sollte funktionieren. Es ist einfach und schnell.

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

Der Oj-Edelstein wird für JRuby nicht funktionieren. Für JRuby kann dies ( https://github.com/ralfstx/minimal-json ) oder dies ( https://github.com/clojure/data.json ) sein Gute Möglichkeiten.

2
John Moore