2013-08-23 6 views
10

私は次のJSONをaesonで解析しようとしています。フィールド名が予約済みのキーワードを含むJSONを解析します。

{ 
    "data": [ 
     { 
      "id": "34", 
      "type": "link", 
      "story": "foo" 
     }, 
     { 
      "id": "35", 
      "type": "link", 
      "story": "bar" 
     } 
    ] 
} 

私は無視したいフィールドがたくさんあるので、それはI should use GHC genericsようです。しかし、datatypeのようなHaskellキーワードを使用するデータ型定義を書くにはどうすればいいですか?もちろん、次のようになります:parse error on input `data'

data Feed = Feed {data :: [Post]} 
    deriving (Show, Generic) 

data Post = Post { 
     id :: String, 
     type :: String, 
     story :: String 
    } 
    deriving (Show, Generic) 

答えて

13

あなたはGHC.Genericsに頼らず、独自のFromJSONToJSONインスタンスを書くことができます。これはまた、データ表現とJSON表現に異なるフィールド名を使用できることを意味します。ポストのため

例インスタンス:

{-# LANGUAGE OverloadedStrings #-} 
import Control.Applicative 
import Data.Aeson 
import qualified Data.ByteString.Lazy as LBS 

data Post = Post { 
     postId :: String, 
     typ :: String, 
     story :: String 
    } 
    deriving (Show) 

instance FromJSON Post where 
    parseJSON (Object x) = Post <$> x .: "id" <*> x.: "type" <*> x .: "story" 
    parseJSON _ = fail "Expected an Object" 

instance ToJSON Post where 
    toJSON post = object 
    [ "id" .= postId post 
    , "type" .= typ post 
    , "story" .= story post 
    ] 

main :: IO() 
main = do 
    print $ (decode $ Post "{\"type\": \"myType\", \"story\": \"Really interresting story\", \"id\" : \"SomeId\"}" :: Maybe Post) 
    LBS.putStrLn $ encode $ Post "myId" "myType" "Some other story" 

同じフィードのために行うことができます。フィールドを無視する必要がない場合は、Data.Aeson.THからderiveJSONを使用することもできます。これは、最初の引数としてフィールド名を変更する機能を使用します。

+0

ありがとうございます。このアプローチを 'Generic'と組み合わせることも可能でしょうか? 「Post」型は 'type'属性を持たなかったので、' Feed'の 'parseJSON'を手動で実装している間に' Post derived(Generic) 'を持つことはできないと思われます。 。 – mb21

+0

最後に、私はJSONの 'data'属性を取り除くためだけに' Feed'データ型が本当に必要かどうか、何とか投稿に直接アクセスできるのかどうか疑問に思っていました。 – mb21

+1

@ mb21 [a]はFromJSON/ToJSONインスタンスを持っていますので、Postのリストを直列化するだけの場合は、 'encode listOfPosts'で直接行います。また、このアプローチをGenericと組み合わせて、Genericを使用して他のインスタンスと同様にPostのインスタンスを派生させ、Feedのインスタンスを手動で記述することができます。それだけで動作します。 – bennofs

関連する問題