Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从双嵌套响应解析JSON_Json_Crystal Lang - Fatal编程技术网

如何从双嵌套响应解析JSON

如何从双嵌套响应解析JSON,json,crystal-lang,Json,Crystal Lang,如果我得到一个cars端点的JSON响应: { data: { cars: [ { make: "Tesla", model: "S" } ] } } 我有一辆class汽车: class Car JSON.mapping( make: String, model: String ) end 如何解析响应以使根向下两级?我知道我可以从_json(json_string,“data”)执行Car.from,但无法找到指定另一个根键的方

如果我得到一个
cars
端点的JSON响应:

{
  data: {
    cars: [
      { make: "Tesla", model: "S" }
    ]
  }
}
我有一辆class
汽车

class Car
  JSON.mapping(
    make: String,
    model: String
  )
end
如何解析响应以使根向下两级?我知道我可以从_json(json_string,“data”)执行
Car.from,但无法找到指定另一个根键的方法


如果没有办法做到这一点,那么在不为
汽车
级别创建另一个类的情况下,最简单的方法是什么?

这里有几种方法

一个简单但效率最低的方法是只解析两次:

cars = Array(Car).from_json(JSON.parse(json)["data"]["cars"].to_json)

然后,正如您所提到的,您可以为外部类创建映射。没有比你拥有的更快的方法了:

class Root
  JSON.mapping(data: Data)
end

class Data
  JSON.mapping(cars: Array(Car))
end

class Car
  JSON.mapping(
    make: String,
    model: String
  )
end

cars = Root.from_json(json).data.cars

或者,如果您喜欢使用
JSON::Serializable
API:

class Root
  include JSON::Serializable
  property data : Data
end

class Data
  include JSON::Serializable
  property cars : Array(Car)
end

class Car
  include JSON::Serializable
  property  make : String
  property  model : String
end

cars = Root.from_json(json).data.cars

最后,最后一种方法是直接驱动
JSON::PullParser
API:

parser = JSON::PullParser.new(json)
cars = nil
parser.on_key("data") do
  parser.on_key("cars") do
    cars = Array(Car).new(parser)
  end
end

这里有几种方法可供选择

一个简单但效率最低的方法是只解析两次:

cars = Array(Car).from_json(JSON.parse(json)["data"]["cars"].to_json)

然后,正如您所提到的,您可以为外部类创建映射。没有比你拥有的更快的方法了:

class Root
  JSON.mapping(data: Data)
end

class Data
  JSON.mapping(cars: Array(Car))
end

class Car
  JSON.mapping(
    make: String,
    model: String
  )
end

cars = Root.from_json(json).data.cars

或者,如果您喜欢使用
JSON::Serializable
API:

class Root
  include JSON::Serializable
  property data : Data
end

class Data
  include JSON::Serializable
  property cars : Array(Car)
end

class Car
  include JSON::Serializable
  property  make : String
  property  model : String
end

cars = Root.from_json(json).data.cars

最后,最后一种方法是直接驱动
JSON::PullParser
API:

parser = JSON::PullParser.new(json)
cars = nil
parser.on_key("data") do
  parser.on_key("cars") do
    cars = Array(Car).new(parser)
  end
end

谢谢您的帮助。我希望有更像
Array(Car)的东西。来自_json(json.body,“data”,“cars”)
,但这似乎是最好的。自己实现这样的东西并不难。请看这里的示意图:但我认为像这样的API永远不会简单到可以理解,同时也不会灵活到可以包含在stdlib中。谢谢你。我希望有更像
Array(Car)的东西。来自_json(json.body,“data”,“cars”)
,但这似乎是最好的。自己实现这样的东西并不难。请看这里的示意图:但我认为这样的API永远不会简单到可以理解,同时也不会灵活到可以包含在stdlib中。