Aeson:用 Haskell 中的未知密钥解析 JSON
Aeson: parse JSON with unknown key in Haskell
我想在 Haskell 中使用 Aeson 解析以下 JSON:
{
"foo": {
"name": "name 1",
"location": "location 1"
},
"bar": {
"name": "name 2",
"location": "location 2"
}
}
密钥 name
和 location
已知,但 foo
和 bar
未知。
我想将 JSON 数据加载为以下数据类型 ([Entry]
) 的列表:
data Entry = Entry
{ id :: String -- "foo" or "bar" etc.
, name :: String -- "name 1" or "name 2" etc.
, location :: String -- "location 1" or "location 2" etc.
} deriving Show
我的第一次尝试如下(还没有成功):
instance FromJSON Entry where
parseJSON (Object o) = do
map (\(id, (name, location)) -> Entry id name location) o
parseJSON o
如何正确解析 JSON?
这应该有效:
{-# LANGUAGE FlexibleInstances, OverloadedStrings #-}
import Data.Aeson
import Data.Aeson.Types
import Data.HashMap.Strict
data Entry = Entry
{ id :: String
, name :: String
, location :: String
}
deriving Show
instance FromJSON [Entry] where
parseJSON x =
parseJSON x >>= mapM parseEntry . toList
parseEntry :: (String, Value) -> Parser Entry
parseEntry (i, v) =
withObject "entry body" (\ o ->
Entry i <$> o .: "name" <*> o .: "location")
v
考虑到您想要解析条目的方式,
你不能真正解析单个条目,只有
一次几个,因为你需要外部对象结构。
[Entry]
的 JSON 解析器然后首先解析外部
对象作为哈希图并使用 toList
将其转换为对列表,
然后用 parseEntry
.
处理每个结果 (String, Value)
对
我想在 Haskell 中使用 Aeson 解析以下 JSON:
{
"foo": {
"name": "name 1",
"location": "location 1"
},
"bar": {
"name": "name 2",
"location": "location 2"
}
}
密钥 name
和 location
已知,但 foo
和 bar
未知。
我想将 JSON 数据加载为以下数据类型 ([Entry]
) 的列表:
data Entry = Entry
{ id :: String -- "foo" or "bar" etc.
, name :: String -- "name 1" or "name 2" etc.
, location :: String -- "location 1" or "location 2" etc.
} deriving Show
我的第一次尝试如下(还没有成功):
instance FromJSON Entry where
parseJSON (Object o) = do
map (\(id, (name, location)) -> Entry id name location) o
parseJSON o
如何正确解析 JSON?
这应该有效:
{-# LANGUAGE FlexibleInstances, OverloadedStrings #-}
import Data.Aeson
import Data.Aeson.Types
import Data.HashMap.Strict
data Entry = Entry
{ id :: String
, name :: String
, location :: String
}
deriving Show
instance FromJSON [Entry] where
parseJSON x =
parseJSON x >>= mapM parseEntry . toList
parseEntry :: (String, Value) -> Parser Entry
parseEntry (i, v) =
withObject "entry body" (\ o ->
Entry i <$> o .: "name" <*> o .: "location")
v
考虑到您想要解析条目的方式, 你不能真正解析单个条目,只有 一次几个,因为你需要外部对象结构。
[Entry]
的 JSON 解析器然后首先解析外部
对象作为哈希图并使用 toList
将其转换为对列表,
然后用 parseEntry
.
(String, Value)
对