2016-08-14 150 views
0

我無法解析以下JSON結構中的標記。解析器只適用於當我聲明它是tags :: !Array它失敗時,我宣佈它爲tags :: [Tag]Haskell Aeson嵌套數組JSON

爲什麼?

{ 
    "response": { 
    "status": "ok", 
    "results": [ 
     { 
     "type": "article", 
     "fields": { 
      "wordcount": "497" 
     }, 
     "tags": [ 
      { 
      "id": "profile/barryglendenning" 
      } 
     ] 
     } 
    ] 
    } 
} 



data Field = Field{ 
    wordcount :: Int 
} deriving (Show) 

instance FromJSON Field where 
    parseJSON (Object o) = Field <$> (o .: "wordcount") 
    parseJSON _ = mzero 


data Tag = Tag{ 
    id :: Text 
} deriving (Show) 

instance FromJSON Tag where 
    parseJSON (Object o) = Tag <$> (o .: "id") 
    parseJSON _ = mzero 

data SearchResult = SearchResult { 
    type:: Text, 
    field :: Field, 
    tags :: !Array 
} deriving (Show) 

instance FromJSON SearchResult where 
    parseJSON (Object o) = do 
     let t1 = o .: "type" 
     let t2 = o .: "fields" 
     let t3 = o .: "tags" 
     SearchResult <$> t1 <*> t2 <*> t3 
    parseJSON _ = mzero 


data ContentrResult = ContentrResult { 
    results :: [SearchResult], 
    status :: Text 
} deriving (Show) 

instance FromJSON ContentrResult where 
    parseJSON (Object o) = do 
     r <- o .: "response" 
     ContentrResult <$> r .: "results" 
         <*> r .: "status" 
    parseJSON _ = mzero 
+2

什麼是你所得到的確切的錯誤? – user2847643

+0

它可能與你的問題無關,但我不會指定一個記錄字段「id」,因爲那樣你就會在前奏中產生歧義。 –

+0

順便說一句,命名一個字段'type'是一個語法錯誤 –

回答

1

Nothing對調試不是很有用嗎?

我設法讓您的示例JSON解析tags作爲[Tag]。我想知道你的錯誤是否可能與wordcount字段在JSON中是String而不是Number有關。

下面是更多或更少的自包含的例子,我改變了例子JSON單詞計數多項:

{-# LANGUAGE OverloadedStrings #-} 
{-# LANGUAGE QuasiQuotes #-} 

module Main where 

import Lib (str) 

import Control.Monad (mzero) 
import Data.Aeson 
import qualified Data.ByteString.Lazy.Char8 as LBSC 
import Data.Text 

data Field = Field { 
    wordcount :: Int 
} deriving (Show) 

instance FromJSON Field where 
    parseJSON (Object o) = Field <$> o .: "wordcount" 
    parseJSON _ = mzero 

data Tag = Tag { 
    id :: Text 
} deriving (Show) 

instance FromJSON Tag where 
    parseJSON (Object o) = Tag <$> (o .: "id") 
    parseJSON _ = mzero 

data SearchResult = SearchResult { 
    typ :: Text, 
    fields :: Field, 
    tags :: [Tag] 
} deriving (Show) 

instance FromJSON SearchResult where 
    parseJSON (Object v) = SearchResult <$> v .: "type" <*> v .: "fields" <*> v .: "tags" 
    parseJSON _ = mzero 

data ContentrResult = ContentrResult { 
    results :: [SearchResult], 
    status :: Text 
} deriving (Show) 

instance FromJSON ContentrResult where 
    parseJSON (Object v) = ContentrResult <$> v.: "results" <*> v .: "status" 
    parseJSON _ = mzero 

data Response = Response { 
    response :: ContentrResult 
} deriving (Show) 

instance FromJSON Response where 
    parseJSON (Object v) = Response <$> v .: "response" 
    parseJSON _ = mzero 

responseJson :: String 
responseJson = [str| 
    { 
    "response": { 
     "status": "ok", 
     "results": [ 
     { 
      "type": "article", 
      "fields": { 
      "wordcount": 497 
      }, 
      "tags": [ 
      { 
       "id": "profile/barryglendenning" 
      } 
      ] 
     } 
     ] 
    } 
    } 
|] 

main :: IO() 
main = do 
    print r 
    putStrLn "" 
    where 
     r :: Maybe Response 
     r = decode (LBSC.pack responseJson)