2013-01-03 134 views
2

我需要在Ruby中實現一個簡單的shell實用程序,它從文件中解析JSON並從中返回特定的字段。要解析如何從Ruby中的JSON獲取特定的字段

JSON例子:

{"status": "fail", "messages": ["Out of capacity"]} 

{"status": "success", "messages": [], "result": {"node": {"ip": "1.2.3.4", "description": "", "id": 974, "name": "VM#3"}}} 

想法是創建一個CLI工具有兩個參數:JSON文件從JSON閱讀並現場提取:

./get_json_field.rb ~/tmp.XXXXXX 'result.node.ip' 
./get_json_field.rb ~/tmp.XXXXXX 'messages.0' 

我掙扎如何將第二個參數映射到Ruby中已解析的JSON數據結構。我可以肯定地寫一個迭代器,將字符串拆分爲一個數組,使用點作爲分隔符,逐項遍歷它,但這看起來不像是優雅的解決方案。

任何建議更優雅的方式?

+0

爲什麼沒有,似乎高貴?我覺得很自然! –

+0

我還在想那個地圖式的解決方案,那個 –

回答

2

沒有什麼錯分割字符串,並要通過它的部分:

require 'json' 

data1 = JSON.load('{"status": "fail", "messages": ["Out of capacity"]}') 
data2 = JSON.load('{"status": "success", "messages": [], "result": {"node": {"ip": "1.2.3.4", "description": "", "id": 974, "name": "VM#3"}}}') 

def get_from_json(data, query) 
    query.split('.').inject(data) do |memo, key| 
    key = key.to_i if memo.is_a? Array 
    memo.fetch(key) 
    end 
end 

get_from_json(data1, 'messages.0')  # => "Out of capacity" 
get_from_json(data2, 'result.node.ip') # => "1.2.3.4" 
+0

是的。我正要寫這樣的東西。你只是忘了轉換數字。因爲獲取'1'與獲取1不同1 –

+0

@IsmaelAbreu更新以處理數字。 –

1

jq看看它可能已經這樣做了,你在找什麼。

jq .messages[0] 
jq .node.message.ip 

http://stedolan.github.com/jq/

+0

不錯的工具!非常感謝! –