【问题标题】:Parsing JSON in Ruby (like XPATH)在 Ruby 中解析 JSON(如 XPATH)
【发布时间】:2014-04-29 10:26:43
【问题描述】:

我有一个从查询返回到 Google Books API 的 JSON 文档,例如:

{ “项目”: [ { “卷信息”:{ “行业标识符”:[ { “类型”:“其他”, “标识符”:“OCLC:841804665” } ] } }, { “卷信息”:{ “行业标识符”:[ { “类型”:“ISBN_10”, “标识符”:“156898118X”...

我需要 ISBN 编号(类型:ISBN_10 或 ISBN_13),并且我编写了一个简单的循环来遍历已解析的 JSON (parsed = json.parse(my_uri_response))。在这个循环中,我有一个next if k['type'] = "OTHER",它将“type”设置为“OTHER”。

如何最好地从我的 JSON 示例中提取一个 ISBN 号?不是全部,只有一个。

XPath 搜索之类的东西会很有帮助。

【问题讨论】:

  • 那是因为您使用的是k['type'] = "OTHER" 而不是k['type'] == "OTHER",请注意单对等与双等。

标签: ruby json


【解决方案1】:

JSONPath 可能正是您想要的:

require 'jsonpath'

json = #your raw JSON above

path = JsonPath.new('$..industryIdentifiers[?(@.type == "ISBN_10")].identifier')

puts path.on(json)

结果:

156898118X

请参阅this page,了解 XPath 如何转换为 JSONPath。它帮助我确定了上面的 JSONPath。

【讨论】:

  • 你测试过这个吗?如此处所述:github.com/joshbuddy/jsonpath/issues/17 未实现字符串函数...
  • 它们不是,这就是为什么我在 ?( ) 中使用“脚本表达式”和 Ruby 语法而不是 XPath 样式表达式。
【解决方案2】:

怎么样:

parsed['items'].map { |book| 
  book['volume_info']['industryIdentifiers'].find{ |prop| 
    ['ISBN_10', 'ISBN_13'].include? prop['type']
  }['identifier'] 
}

如果您收到undefined method [] for nil:NilClass,这意味着您在items 数组中有一个元素,它没有volume_info 键,或者您有一个包含一组industryIdentifiers 的卷而没有ISBN。下面的代码应该涵盖所有这些情况(+ 有volumeInfo 而没有industry_identifiers 的情况:

parsed['items'].map { |book| 
  identifiers = book['volume_info'] && book['volume_info']['industryIdentifiers']
  isbn_identifier = idetifiers && identifiers.find{ |prop| 
    ['ISBN_10', 'ISBN_13'].include? prop['type']}['identifier']
  }
  isbn_identifier && isbn_identifier['identifier']
}.compact

如果你碰巧有andand gem,这可能写成:

parsed['items'].map { |book| 
  book['volume_info'].andand['industryIdentifiers'].andand.find{ |prop| 
    ['ISBN_10', 'ISBN_13'].include? prop['type']
  }.andand['identifier'] 
}.compact

请注意,这将只为每卷返回一个 ISBN。如果您有带有ISBN_10ISBN_13 的卷并且您想要同时获得这两个卷,而不是find,您需要使用select 方法和.map{|i| i[:identifier]} 代替.andand['identifier']

【讨论】:

    猜你喜欢
    • 2021-06-15
    • 2017-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多