在 Elm 中,如何解码嵌套 JSON 中的 JSON 对象
In Elm, how to decode a JSON object inside nested JSON
我使用 Elm 0.19.1 和 NoRedInk/elm-json-decode-pipeline/1.0.0
我的飞机类型是
type alias Aircraft = {name:String}
为此,我有以下解码器:
aircraftDecoder : Json.Decode.Decoder Aircraft
aircraftDecoder =
Json.Decode.succeed Aircraft
|> Json.Decode.Pipeline.required "name" Json.Decode.string
不幸的是,解码器抱怨我说:"BadBody "给定值有问题:(...)"
这是因为实际上我感兴趣的区域周围充满噪音(来自 HATEOAS api),如下所示:
{
"_embedded" : {
"aircrafts" : [ {
"name" : "AC01",
"_links" : {
"self" : {
"href" : "http://localhost:8080/aircrafts/1"
},
"aircraft" : {
"href" : "http://localhost:8080/aircrafts/1"
}
}
}, {
"name" : "AC01",
"_links" : {
"self" : {
"href" : "http://localhost:8080/aircrafts/2"
},
"aircraft" : {
"href" : "http://localhost:8080/aircrafts/2"
}
}
} ]
},
"_links" : {
"self" : {
"href" : "http://localhost:8080/aircrafts{?page,size,sort}",
"templated" : true
},
"profile" : {
"href" : "http://localhost:8080/profile/aircrafts"
}
},
"page" : {
"size" : 20,
"totalElements" : 4,
"totalPages" : 1,
"number" : 0
}
}
我怎样才能更改代码,并继续使用管道,这样解码器就不会被这些噪音弄丢了?
我听说过一些关于使用 Json.Decode.at 的信息,但文档不够好,无法让我获得正确的代码。
以下应该有效:
aircraftNameDecoder : Json.Decode.Decoder String
aircraftNameDecoder =
Json.Decode.map (Maybe.withDefault "" << List.head) <|
Json.Decode.at [ "_embedded", "aircrafts" ] <|
Json.Decode.list (Json.Decode.field "name" Json.Decode.string)
aircraftDecoder : Json.Decode.Decoder Aircraft
aircraftDecoder =
Json.Decode.succeed Aircraft
|> Json.Decode.Pipeline.custom aircraftNameDecoder
有关 Json.Decode.at
的更多文档,请参阅 elm/json。
据我所知,问题在于:
- 此刻,您的解码器可能非常适合解码单个
Aircraft
- 但是,您的 JSON 有一个列表
Aircraft
s
- 另外,你的解码器不知道在哪里,在JSON中,它可能会找到
Aircraft
s
而且你知道,对于 Elm Aircraft
和 List Aircraft
是完全不同的节拍(它们应该是)。无论如何,解决方案分为两步:
- 告诉解码器 JSON 结构中的
Aircraft
s
- 解析
List Aircraft
而不是单个 Aircraft
按照您的代码并从 Json.Decode
导入 at
和 list
,代码可能如下所示:
listAircraftDecoder : Json.Decode.Decoder List Aircraft
listAircraftDecoder =
at ["_embedded", "aircrafts"] (list aircraftDecoder)
这意味着我们现在的目标是 Aircraft
的列表,并且该列表是 JSON 中的一个数组。从 JSON 根开始,获取 属性 "_embedded"
以及其中的 属性 "aircrafts"
。这是一个数组,Elm的list
知道如何处理它
最后,我们只需要告诉 Elm 的 list
将 JSON 数组的每个元素传递给特定的解码器——在我们的例子中是您的 aircraftDecoder
。
这有意义吗?
我使用 Elm 0.19.1 和 NoRedInk/elm-json-decode-pipeline/1.0.0
我的飞机类型是
type alias Aircraft = {name:String}
为此,我有以下解码器:
aircraftDecoder : Json.Decode.Decoder Aircraft
aircraftDecoder =
Json.Decode.succeed Aircraft
|> Json.Decode.Pipeline.required "name" Json.Decode.string
不幸的是,解码器抱怨我说:"BadBody "给定值有问题:(...)" 这是因为实际上我感兴趣的区域周围充满噪音(来自 HATEOAS api),如下所示:
{
"_embedded" : {
"aircrafts" : [ {
"name" : "AC01",
"_links" : {
"self" : {
"href" : "http://localhost:8080/aircrafts/1"
},
"aircraft" : {
"href" : "http://localhost:8080/aircrafts/1"
}
}
}, {
"name" : "AC01",
"_links" : {
"self" : {
"href" : "http://localhost:8080/aircrafts/2"
},
"aircraft" : {
"href" : "http://localhost:8080/aircrafts/2"
}
}
} ]
},
"_links" : {
"self" : {
"href" : "http://localhost:8080/aircrafts{?page,size,sort}",
"templated" : true
},
"profile" : {
"href" : "http://localhost:8080/profile/aircrafts"
}
},
"page" : {
"size" : 20,
"totalElements" : 4,
"totalPages" : 1,
"number" : 0
}
}
我怎样才能更改代码,并继续使用管道,这样解码器就不会被这些噪音弄丢了?
我听说过一些关于使用 Json.Decode.at 的信息,但文档不够好,无法让我获得正确的代码。
以下应该有效:
aircraftNameDecoder : Json.Decode.Decoder String
aircraftNameDecoder =
Json.Decode.map (Maybe.withDefault "" << List.head) <|
Json.Decode.at [ "_embedded", "aircrafts" ] <|
Json.Decode.list (Json.Decode.field "name" Json.Decode.string)
aircraftDecoder : Json.Decode.Decoder Aircraft
aircraftDecoder =
Json.Decode.succeed Aircraft
|> Json.Decode.Pipeline.custom aircraftNameDecoder
有关 Json.Decode.at
的更多文档,请参阅 elm/json。
据我所知,问题在于:
- 此刻,您的解码器可能非常适合解码单个
Aircraft
- 但是,您的 JSON 有一个列表
Aircraft
s - 另外,你的解码器不知道在哪里,在JSON中,它可能会找到
Aircraft
s
而且你知道,对于 Elm Aircraft
和 List Aircraft
是完全不同的节拍(它们应该是)。无论如何,解决方案分为两步:
- 告诉解码器 JSON 结构中的
Aircraft
s - 解析
List Aircraft
而不是单个Aircraft
按照您的代码并从 Json.Decode
导入 at
和 list
,代码可能如下所示:
listAircraftDecoder : Json.Decode.Decoder List Aircraft
listAircraftDecoder =
at ["_embedded", "aircrafts"] (list aircraftDecoder)
这意味着我们现在的目标是 Aircraft
的列表,并且该列表是 JSON 中的一个数组。从 JSON 根开始,获取 属性 "_embedded"
以及其中的 属性 "aircrafts"
。这是一个数组,Elm的list
知道如何处理它
最后,我们只需要告诉 Elm 的 list
将 JSON 数组的每个元素传递给特定的解码器——在我们的例子中是您的 aircraftDecoder
。
这有意义吗?