2014-02-12 77 views
5

我想教自己ruby並解決工作中的問題。我的最終目標是從API中提取出JSON響應中的許多字段中的三個,並將其操縱並轉儲爲CSV以用於執行報告。ruby​​:從嵌套json中提取字段

的JSON的結構是:

{ 
    "status": 200, 
    "data": { 
    "total": 251, 
    "alerts": [ 
     { 
     "dataPoint": "x", 
     "ackedBy": "x", 
     "dataSourceInstance": "x", 
     "dataSource": "x", 
     "host": "x", 
     "endOn": 0, 
     "ackedOn": 1385085190, 
     "dataSourceInstanceId": 588384, 
     "hostId": 935, 
     "type": "alert", 
     "dataSourceId": 694, 
     "ackedOnLocal": "2013-11-21 17:53:10 PST", 
     "id": 6170384, 
     "startOn": 1385084917, 
     "thresholds": "!= 1 1 1", 
     "endOnLocal": "", 
     "level": "error", 
     "ackComment": "x", 
     "value": "No Data", 
     "hostDataSourceId": 211986, 
     "acked": true, 
     "hostGroups": [{ 
      "alertEnable": true, 
      "createdOn": 1362084592, 
      "id": 21, 
      "parentId": 78, 
      "description": "", 
      "appliesTo": "", 
      "name": "2600hz", 
      "fullPath": "x" 
     }], 
     "startOnLocal": "2013-11-21 17:48:37 PST" 
     }, 

具體地說我想提取出dataPointstartOnackedOn

我想我需要首先提取總價值,所以我知道我有多少警報。這將幫助我循環通過警報實例。

*url = "https://xyz" 
uri = URI(url) 
http = Net::HTTP.new(uri.host, 443) 
http.use_ssl = true 
http.verify_mode = OpenSSL::SSL::VERIFY_NONE 
req = Net::HTTP::Get.new(uri.request_uri) 
response = http.request(req) 

# Make sure we had a proper web response 
if response.code == '200' then 

# Set up that the total is two levels deep in the json 
path = JsonPath.new('$.total') 

# Extract out total field into variable 
totalAlerts = path.on(response) 

# Print hash to confirm value 
pp totalAlerts 

end* 

我被困在試圖提取出總數。輸出不顯示任何內容:

sudo ruby alerts.rb 
[] 

有沒有更好的方法來做到這一點?

回答

10

試試這個:

# just for demonstration, you would probably do json = JSON.parse(response) 
json = { 
    "status": 200, 
    "data": { 
    "total": 251, 
    "alerts": [ 
     { 
     "dataPoint": "x", 
     "ackedBy": "x", 
     ... 

對於剛剛總:

total = json['data']['total'] 

對於其他值,你問:

json['data']['alerts'].each do |alerts| 
    # do whatever you want with these... 
    alerts['dataPoint'] 
    alerts['startOn'] 
    alerts['ackedOn'] 

現在的問題是,你想要什麼與結果做什麼?你想收集他們到一個新的哈希? json['data']['alerts']是一個數組,因此您必須決定如何收集它們。你可以這樣做:

collected_alerts = { 'dataPoints' => [], 'startOns' => [], 'ackedOns' => [] } 
json['data']['alerts'].each do |alerts| 
    collected_alerts['dataPoints'] << alerts['dataPoint'] 
    collected_alerts['startOns'] << alerts['startOn'] 
    collected_alerts['ackedOns'] << alerts['ackedOn'] 
end 

現在你可以在collected_alerts

+0

所有這些值添加此測試 jsonResponse = JSON.parse(響應) 總= jsonResponse [ '數據'] [ '總' ] pp總計 並且得到以下錯誤: sudo ruby​​ alerts.rb /usr/local/lib/ruby/2.1.0/json/common.rb:155:in'initialize':沒有隱式轉換的Net :: HTTPOK到String(TypeError) \t from /usr/local/lib/ruby/2.1.0/json/common.rb:155:i ñ'新從alerts.rb \t '從/usr/local/lib/ruby/2.1.0/json/common.rb:155:in'解析 \t':37:在'

「 我最終要在將數值加載到散列或數組中以進行操作之後,將其放入csv 謝謝! – achan

+0

讓它成爲JSON.parse(response.body) – DiegoSalazar

+0

我還有兩個問題,然後我完成了。 #計算確認警報並將它存儲在timeToAcks #分鐘是確認時間 - 開始時間,這將使我們秒/ 60分鐘。 timeToAck =(警報[ 'ackedOn'] - 警報[ 'startOns'])/ 60 collected_alerts [ 'timeToAcks'] << timeToAck 當我運行它我得到這個錯誤 alerts.rb:57:在' - ':nil不能從alerts.rb強制插入到Fixnum(TypeError)中:57:在'block中

'中來自alerts.rb:47:在'each'中來自警報。rb:47:在'
' – achan