2013-01-03 4 views
2

J'ai besoin d'implémenter un utilitaire shell simple dans Ruby qui analyse JSON à partir d'un fichier et y renvoie un champ particulier.Comment obtenir un champ particulier de JSON dans Ruby

exemples JSON à parsés:

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

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

L'idée est de créer un utilitaire CLI avec deux paramètres: fichier JSON à lire et sur le terrain de JSON pour extraire:

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

Je me bats comment mapper le deuxième paramètre à la structure de données JSON analysée dans Ruby. Je peux écrire un itérateur à coup sûr, en divisant la chaîne en tableau en utilisant le point comme séparateur et en passant par chaque élément, mais cela ne ressemble pas à une solution élégante.

Des suggestions pour une manière plus élégante?

+0

Pourquoi ne pas sembler elegent? Cela me semble assez naturel! –

+0

Je pense toujours à une solution semblable à une carte pour cela –

Répondre

2

Il n'y a rien de mal avec la chaîne de séparation et en passant par certaines parties:

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

Oui. J'étais sur le point d'écrire quelque chose comme ça. Vous venez d'oublier de convertir des nombres. Parce que fetch '1' n'est pas la même chose que récupérer 1 –

+0

@IsmaelAbreu mis à jour pour gérer les nombres. –

1

Jetez un oeil à jq il pourrait déjà faire ce que vous recherchez.

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

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

+0

Bel outil! Merci beaucoup! –

Questions connexes