2013-08-23 15 views
10

Aşağıdaki JSON'u aeson ile ayrıştırmaya çalışıyorum. Ben görmezden istediğiniz alanı bir sürü olduğundanAyrılmış anahtar kelimeler içeren alan adlarıyla JSON'yi ayrıştırın

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

, bu I should use GHC generics görünüyor. Ancak, data ve type gibi Haskell anahtar sözcüklerini kullanan bir veri türü tanımı nasıl yazılır? Tabii şu verir: Sen GHC.Generics dayanmadan kendi FromJSON ve ToJSON örneklerini yazabilir 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) 

cevap

13

. Bu aynı zamanda veri gösterimi ve JSON gösterimi için farklı alan adlarını kullanabileceğiniz anlamına gelir. Post için

Örnek örnekleri:

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

aynı Yem için yapılabilir. Alanları göz ardı etmek zorunda kalmadıysanız, alan adlarını ilk argüman olarak değiştirmek için Data.Aeson.TH'dan deriveJSON kullanabilirsiniz.

+0

Teşekkürler, güzel çalışıyor! Bu yaklaşımı 'Jenerik' ile birleştirmek de mümkün olabilir mi? "Post" türünde "type" özelliği bulunmadığını söyleyin, "Feed" in "parseJSON" komutunu manuel olarak uygulayarak Post türetme (Generic) 'e sahip olamayacağım ve daha sonra bunları sorudaki gibi birleştiremeyeceğim . – mb21

+0

Son olarak, JSON'daki "data" özniteliğinden kurtulmak için veya Feed'e doğrudan bir şekilde ulaşıp ulaşamayacağımı öğrenmek için "Feed" veri türüne gerçekten ihtiyacım olup olmadığını merak ediyordum. – mb21

+1

@ mb21 [a] FromJSON/ToJSON örneklerine sahiptir, yani yapmak istediğiniz tek şey İletilerin bir listesini serileştirmekse, bunu doğrudan 'encode listOfPosts' ile yapın. Ve yaklaşımı Generic ile birleştirebilirsiniz, sadece Post için örneği Jenerik kullanarak herhangi bir başka örnek gibi alın ve örneği Feed'e elle yazınız. Sadece işe yarıyor. – bennofs