I'm having trouble parsing JSON text in the form
{
"Person1": {
"name": "John Doe",
"job" : "Accountant",
"id": 123
},
"Person2": {
"name": "Jane Doe",
"job" : "Secretary",
"id": 321
}}
I define a new data type as follows
data Person = Person
{ name :: String
, job :: String
, id :: Int } deriving Show
But am having trouble defining an instance of FromJSON in this case.
Now if the JSON text were in the form of
{
"People": [
{
"name": "John Doe",
"job": "Accountant",
"id": 123
},
{
"name": "Jane Doe",
"job": "Secretary",
"id": 321
}]
}
I could write
instance FromJSON person where
parseJSON = withObject "Person" $ \obj -> Person
<$> obj .: "name"
<*> obj .: "job"
<*> obj .: "id"
But I don't know how to translate this pattern to the other format.
A JSON dictionary, such as
{ "foo" : "bar" }can be decoded into Maps such asMapfrom the containers package orHashMapfrom unordered-containers. Once you have your FromJSON instance for Person then just useAeson.decodeto get aMap Text Person. If you'd like to get[Person]then you could further useData.Map.elems.For example:
The interesting bit is that
Aeson.decodeis returning a typeMap String Person. Everything is is just there to make a complete demonstration.You can test this with the input:
To see output of:
If you want to drop the
Person1andPerson2tags then just get the elements of the Map usingData.Map.elems.