Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.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
Elixir-对结构的嵌套JSON解析_Json_Elixir - Fatal编程技术网

Elixir-对结构的嵌套JSON解析

Elixir-对结构的嵌套JSON解析,json,elixir,Json,Elixir,免责声明:我已经检查了这个问题,但它没有回答我的问题 我试图想出一种方法来对JSON进行嵌套结构解析。例如: {"name": "blah blah", "address": {"street": "smthing"}} 我想达到这个结果: %User{name: "blah blah", address: %Address{street: "smthing"}} 因为这样就更容易插入验证(使用for exapmle) 我知道毒药支持“as struct”选项,但它不提供嵌套。将对上述内容进

免责声明:我已经检查了这个问题,但它没有回答我的问题

我试图想出一种方法来对JSON进行嵌套结构解析。例如:

{"name": "blah blah", "address": {"street": "smthing"}}
我想达到这个结果:

%User{name: "blah blah", address: %Address{street: "smthing"}}
因为这样就更容易插入验证(使用for exapmle)

我知道毒药支持“as struct”选项,但它不提供嵌套。将对上述内容进行分析:

%User{name: "blah blah", address: %{"street" => "smthing"}}. 
我知道我可以为模块
User
编写一个解码器实现,但我猜这不是预期的用例,也不是通用的

当我想知道一个实现时,我找不到一种方法来判断atom是否是一个模块。。。也许我必须使用
:code.是否加载了(模块名称)


无论如何,在尝试实现之前,我想知道是否有我看不到的东西。

目前,我知道的唯一选择是为
毒药解码器提供您自己的实现。
(注意后面的
r
)协议。这还有一个额外的好处,就是您可以在一个地方进行这些转换,只需将
as:User
写入即可正确转换地址。例如:

defimpl Poison.Decoder, for: User do
  def decode(task_list, options) do
    Map.update! task_list, :address, fn address ->
      Poison.Decode.decode(address, Keyword.merge(options, as: [Address]))
    end
  end
end
请注意,
decode
的内部调用不是来自
Poison.Decoder
,而是
Poison.decode,模块名称中没有尾随的
r
。如果你使用了错误的,你不会得到一个错误,它只是不起作用,这可能是一个痛苦的调试


从长远来看,我认为需要在“毒药”中做一些工作,以使所有这些都更加有趣。可能是一个宏,它将使编写自定义结构的
Poison.Decoder
实现变得更容易。可能还支持嵌套结构选项,如
as:%User{address:address}
,这应该不太难实现。另外,我认为模块名
Decode
Decoder
太容易混淆,其中一个应该重命名。如果我有时间,也许我会提出这些建议,并用毒药建立一个公关。

我相信现在用毒药就可以做到以上几点:

defmodule User do
  @derive [Poison.Encoder]
  defstruct [:address]
end

defmodule Address do
  @derive [Poison.Encoder]
  defstruct [:street]
end

Poison.decode(response, as: %User{address: %Address{}})

如果我这样做的话,可能更通用的方法是实现一个通用解码器,我将
使用BaseDecoder
,然后在
def\uu中使用uu(u),do:etc
来定义协议的实现。但是我必须知道原子是否是一个有效的模块,它是一个结构。我个人认为这有点太神奇了,但是,嘿,为什么不;-)当然,这个设置可以简化,但我更喜欢更明确的方法。我已经为此打开了一个Github问题,让我们看看原始作者的想法,然后也许我会尝试实现它。这对毒药2.0非常有效。谢谢@Maikon