2013-06-24 17 views
11

私は、任意のキーを持つ入れ子になったJSONオブジェクトをたくさん持っています。 Aは、BCが前もって分かっていないAESON-Haskellの任意のJSONキー

{ 
    "A": { 
     "B": { 
      "C": "hello" 

     } 
    } 

} 

。それらの3つのそれぞれは に兄弟を持つこともできます。

これをAesonのカスタムタイプに解析する方法があるかどうかは、私が考えているのは、 です。私がやっているのは、それをAeson Objectにロードすることです。

この種類のJSON オブジェクトに対して、FromJSONを実装する方法を教えてください。

ありがとうございます!

編集

{ 
    "USA": { 
     "California": { 
      "San Francisco": "Some text" 
     } 
    }, 
    "Canada": { 
     ... 
    } 
} 

これは...

type City   = Map String String 
type Country   = Map String City 
type CountryDatabase = Map String Country 
+1

このJSONをどのように解析したいですか?それは常に3つのネストされたキーと文字列だけを持っていますか? –

+0

解析するカスタムタイプの例を挙げることができますか?私はそれが質問を明確にするだろうと思う。 –

+0

質問がデータ構造のより具体的な例で更新されました。 –

答えて

18

あなたはMap String vFromJSONインスタンスを再利用することができCountryDatabaseにコンパイルする必要があります。次のような何か:

{-# LANGUAGE OverloadedStrings #-} 

import Data.Functor 
import Data.Monoid 
import Data.Aeson 
import Data.Map (Map) 
import qualified Data.ByteString.Lazy as LBS 
import System.Environment 

newtype City = City (Map String String) 
    deriving Show 

instance FromJSON City where 
    parseJSON val = City <$> parseJSON val 

newtype Country = Country (Map String City) 
    deriving Show 

instance FromJSON Country where 
    parseJSON val = Country <$> parseJSON val 

newtype DB = DB (Map String Country) 
    deriving Show 

instance FromJSON DB where 
    parseJSON val = DB <$> parseJSON val 

main :: IO() 
main = do 
    file <- head <$> getArgs 
    str <- LBS.readFile file 
    print (decode str :: Maybe DB) 

出力:

[email protected]:/tmp/shum$ cat in.js 
{ 
    "A": { 
     "A1": { 
      "A11": "1111", 
      "A22": "2222" 
     } 
    }, 
    "B": { 
    } 
} 
[email protected]:/tmp/shum$ runhaskell test.hs in.js 
Just (DB (fromList [("A",Country (fromList [("A1",City (fromList [("A11","1111"),("A22","2222")]))])),("B",Country (fromList []))])) 
[email protected]:/tmp/shum$ 

PS:あなたは私だけ明確にするためにそれらを使用し、newtype Sなしでそれを行うことができます。

+0

この回答は非常に役に立ちます!これは文字列以外の値を無視するように変更できますか? (例えば、 '' 1111 "'を '1111'に置き換えると、構文解析が失敗します。) – davidchambers

+0

ToJSONインスタンスはどのように見えますか? – AdHominem