难以用红宝石处理json

时间:2014-07-15 19:38:57

标签: ruby json

我有以下json ......

{
   "NumPages":"17",
   "Page":"1",
   "PageSize":"50",
   "Total":"808",
   "Start":"1",
   "End":"50",
   "FirstPageUri":"/v3/results?PAGE=1",
   "LastPageUri":"/v3/results?PAGE=17",
   "PreviousPageUri":"",
   "NextPageUri":"/v3/results?PAGE=2",
   "User":[
      {
         "RowNumber":"1",
         "UserId":"86938",
         "InternalId":"",
         "CompletionPercentage":"100",
         "DateTimeTaken":"2014-06-18T01:43:25Z",
         "DateTimeLastUpdated":"2014-06-18T01:58:11Z",
         "DateTimeCompleted":"2014-06-18T01:58:11Z",
         "Account":{
            "Id":"655",
            "Name":"Technical Community College"
         },
         "FirstName":"Matthew",
         "LastName":"Knice",
         "EmailAddress":"knice@gmail.com",
         "AssessmentResults":[
            {
               "Title":"Life Factors",
               "Code":"LifeFactors",
               "IsComplete":"1",
               "AttemptNumber":"1",
               "Percent":"58",
               "Readiness":"fail",
               "DateTimeCompleted":"2014-06-18T01:46:00Z"
            },
            {
               "Title":"Learning Styles",
               "Code":"LearnStyles",
               "IsComplete":"0"
            },
            {
               "Title":"Personal Attributes",
               "Code":"PersonalAttributes",
               "IsComplete":"1",
               "AttemptNumber":"1",
               "Percent":"52.08",
               "Readiness":"fail",
               "DateTimeCompleted":"2014-06-18T01:49:00Z"
            },
            {
               "Title":"Technical Competency",
               "Code":"TechComp",
               "IsComplete":"1",
               "AttemptNumber":"1",
               "Percent":"100",
               "Readiness":"pass",
               "DateTimeCompleted":"2014-06-18T01:51:00Z"
            },
            {
               "Title":"Technical Knowledge",
               "Code":"TechKnowledge",
               "IsComplete":"1",
               "AttemptNumber":"1",
               "Percent":"73.44",
               "Readiness":"question",
               "DateTimeCompleted":"2014-06-18T01:58:00Z"
            },
            {
               "Title":"Reading Rate & Recall",
               "Code":"Reading",
               "IsComplete":"0"
            },
            {
               "Title":"Typing Speed & Accuracy",
               "Code":"Typing",
               "IsComplete":"0"
            }
         ]
      },
      {
         "RowNumber":"2",
         "UserId":"8654723",
         "InternalId":"",
         "CompletionPercentage":"100",
         "DateTimeTaken":"2014-06-13T14:37:59Z",
         "DateTimeLastUpdated":"2014-06-13T15:00:12Z",
         "DateTimeCompleted":"2014-06-13T15:00:12Z",
         "Account":{
            "Id":"655",
            "Name":"Technical Community College"
         },
         "FirstName":"Virginia",
         "LastName":"Bustas",
         "EmailAddress":"bigBusta@students.college.edu",
         "AssessmentResults":[
            {
...

我需要在你看到的地方开始处理"用户:"开头的东西(numpages,page,ect)我想忽略。这是我正在处理的处理脚本......

require 'csv'
require 'json'

CSV.open("your_csv.csv", "w") do |csv| #open new file for write
  JSON.parse(File.open("sample.json").read).each do |hash| #open json to parse
    csv << hash.values
  end
end

现在这失败并出现错误:

convert.rb:6:in `block (2 levels) in <main>': undefined method `values' for ["NumPages", "17"]:Array (NoMethodError)

我通过解析器运行了json,它似乎是有效的。只处理&#34;用户&#34;的最佳方式是什么?数据?

3 个答案:

答案 0 :(得分:1)

您必须查看正在创建的JSON对象的结构。这是解析文档的一小部分,这使得查看和理解更容易:

require 'json'

foo = '{"NumPages":17,"User":[{"UserId":12345}]}'

bar = JSON[foo]
# => {"NumPages"=>17, "User"=>[{"UserId"=>12345}]}

bar['User'].first['UserId'] # => 12345

foo包含哈希的JSON。 bar包含JSON解析器在读取foo后创建的Ruby对象。

User是指向哈希数组的关键。因为它是一个数组,所以你必须指定要查看的数组中的哪个哈希值,这是bar['User'].first所做的。

访问该子哈希的另一种方法是:

bar['User'][0]['UserId'] # => 12345

如果数组中有多个哈希值,则可以使用适当的索引值来访问它们。例如,如果有两个哈希值,我想要第二个哈希值:

foo = '{"NumPages":17,"User":[{"UserId":12345},{"UserId":12346}]}'

bar = JSON[foo]
# => {"NumPages"=>17, "User"=>[{"UserId"=>12345}, {"UserId"=>12346}]}

bar['User'].first['UserId'] # => 12345
bar['User'][0]['UserId'] # => 12345
bar['User'][1]['UserId'] # => 12346

  

我想知道我是否会使用JSON.parse走错路(File.open(&#34; sample.json&#34;)。读取).each do | hash |?

是的,你是。你需要了解你正在做什么,并将你的代码分解成可消化的部分,以便它们对你有意义。考虑一下:

require 'csv'
require 'json'

json_object = JSON.parse(File.read("sample.json"))

CSV.open("your_csv.csv", "w") do |csv| #open new file for write

  csv << %w[RowNumber UserID AccountID AccountName FirstName LastName EmailAddress]

  json_object['User'].each do |user_hash|
    puts 'RowNumber: %s' % user_hash['RowNumber']
    puts 'UserID:    %s' % user_hash['UserID']

    account = user_hash['UserID']['Account']
    puts 'Account->Id:   %s' % account['Id']
    puts 'Account->Name: %s' % account['Name']

    puts 'FirstName:    %s' % user_hash['FirstName']
    puts 'LastName:     %s' % user_hash['LastName']
    puts 'EmailAddress: %s' % user_hash['EmailAddress']

    csv << [
      user_hash['RowNumber'],
      user_hash['UserID'],
      account['Id'],
      account['Name'],
      user_hash['FirstName'],
      user_hash['LastName'],
      user_hash['EmailAddress']
    ]
  end
end

这将读取JSON文件并立即将其解析为Ruby对象。文件没有特殊的魔法或其他任何内容,它被打开,读取,关闭,其内容被传递给JSON解析器并分配给json_object

解析后,将打开CSV文件并写入标题行。它可以写成open声明的一部分,但这更清楚地解释了发生了什么。

json_object是一个哈希值,因此要访问'User'数据,您必须使用普通哈希访问json_object['User']User键的值是一个哈希数组,因此需要迭代那些,这是json_object['User'].each所做的,将该数组的哈希元素传递给阻止为user_hash

在该块中,它与访问'User'的值,每个&#34;元素&#34;几乎相同。是一个键/值对,除了'Account',它是一个嵌入式哈希。

答案 1 :(得分:0)

阅读错误消息。调用哈希的each给你一系列带有两个成员的数组(键和值一起)。阵列上没有values方法。在任何情况下,如果你拥有的是一个哈希,那么用each循环它似乎没什么意义;如果您想要哈希中的"User"条目,为什么不预先要求它?

答案 2 :(得分:0)

仅仅为了后代和上下文,这是我最终在其实体中使用的脚本。我需要从URL中提取,并处理结果并将其移动到简单的CSV。我需要将学生编号,名字,姓氏和4个评估中的每个评分分别交给csv。

require 'csv'
require 'json'
require 'curb'

c = Curl::Easy.new('myURL/m/v3/results')
c.http_auth_types = :basic
c.username = 'myusername'
c.password = 'mypassword'
c.perform
json_object = JSON.parse(c.body_str)

CSV.open("your_csv.csv", "w") do |csv| #open new file for write
  csv << %w[UserID FirstName LastName LifeFactors PersonalAttributes TechComp TechKnowledge]
  json_object['User'].each do |user_hash|
    csv << [
      user_hash['UserId'],
      user_hash['FirstName'],
      user_hash['LastName'],
      user_hash['AssessmentResults'][0]['Percent'],
      user_hash['AssessmentResults'][2]['Percent'],
      user_hash['AssessmentResults'][3]['Percent'],
      user_hash['AssessmentResults'][4]['Percent']
    ]
  end
end