2017-03-03 55 views
2

我想解析使用埃宋以下JSON在Haskell:埃宋:未知重點解析JSON在Haskell

{ 
    "foo": { 
     "name": "name 1", 
     "location": "location 1" 
    }, 
    "bar": { 
     "name": "name 2", 
     "location": "location 2" 
    } 
} 

namelocation已知的關鍵,但foobar是未知的。

我想加載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?

回答

6

這應該工作:

{-# 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 

考慮要分析的條目,你真的不能解析單個條目,只 幾個一次的方式, ,因爲你需要外部對象的結構。

的JSON解析器,用於[Entry]然後通過第一解析外 對象作爲散列映射,並使用toList轉動到這對列表進行,然後 處理每個所得(String, Value)對與parseEntry

+1

非常感謝,它完美的作品。什麼是字符串「入門體」? – watain

+3

@watain如果應用給定函數應用於錯誤類型的值,那麼傳遞給'typeMismatch'的參數就是這樣。 – chepner