2014-02-12 3 views
5

나는 루비를 가르치고 직장에서 문제를 해결하려고합니다. 궁극적 인 목표는 API에서 JSON 응답의 여러 필드 중 3 개를 추출하고 경영진의보고를 위해 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" 
     }, 

내가 dataPoint, startOn, ackedOn을 추출 할 구체적으로.

나는 전체 값을 먼저 추출해야한다고 생각하고있어 얼마나 많은 경고가 있는지 알 수 있습니다. 그러면 경고 인스턴스를 반복하는 데 도움이됩니다.

*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 [ '데이터'] [ '총' ] 쪽 총 다음과 같은 오류 얻을 : sudo는 루비 alerts.rb '초기화 /usr/local/lib/ruby/2.1.0/json/common.rb:155:in을 : 인터넷의 암시 적 변환을 :: HTTPOK into String (TypeError) \t /usr/local/lib/ruby/2.1.0/json/common.rb:155:i에서 N 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 분의 초를주는 시작 시간입니다. 57 : - timeToAck = (경고 [ 'ackedOn'] 경고 [ 'startOns']) 그것을 실행할 때/60 collected_alerts [ 'timeToAcks'] << timeToAck 은이 오류를 alerts.rb 얻을에 '- ': alerts.rb : 57 :에서 alerts.rb : 47 : 블록의

에있는 alerts.rb : 57 : Fixnum (TypeError)에 강제로 nil을 강제 적용 할 수 없습니다.rb : 47 : in '
' – achan

관련 문제