2013-01-03 93 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

不错的工具!非常感谢! –