2012-05-15 47 views
11

我正在使用Data.Aeson将一些JSON解析为记录类型。不时数据被添加到JSON,这打破了我的代码为埃宋抱怨东西的效果:容错JSON解析

预期目标的21 名称/值对,但有23名/值

我真的更喜欢以容错的方式解析JSON - 我不在乎是否有更多的字段在以后添加到JSON中,只是解析任何可以!有没有办法实现这种容错?这里是我的代码:

myRecordFromJSONString :: BS.ByteString -> Maybe MyRecord 
myRecordFromJSONString s = case Data.Attoparsec.parse json s of 
    Done _rest res -> Data.Aeson.Types.parseMaybe parseJSON res 
    _    -> Nothing 

我应该补充说,我使用从Data.Aeson.TH deriveJSON生成解析代码。如果我手动编写FromJSON代码,它是容错的,但我不想那么做...

回答

6

如果您使用的是GHC 7.2或7.4,aeson中的新仿制支持不检查额外字段。我不确定这是否由设计决定,但我们使用它是出于同样的原因。

{-# LANGUAGE DeriveGeneriC#-} 
{-# LANGUAGE OverloadedStrings #-} 

import Data.Aeson 
import qualified Data.Aeson.Types 
import Data.Attoparsec 
import qualified Data.ByteString as BS 
import Data.ByteString.Char8() 
import GHC.Generics 

data MyRecord = MyRecord 
    { field1 :: Int 
    } deriving (Generic, Show) 

instance FromJSON MyRecord 

myRecordFromJSONString :: BS.ByteString -> Maybe MyRecord 
myRecordFromJSONString s = case Data.Attoparsec.parse json s of 
    Done _rest res -> Data.Aeson.Types.parseMaybe parseJSON res 
    _    -> Nothing 

main :: IO() 
main = do 
    let parsed = myRecordFromJSONString "{ \"field1\": 1, \"field2\": 2 }" 
    print parsed 

由于'field2'不存在于记录中,所以运行TH将导致失败。 Generic实例返回所需结果:

Just (MyRecord {field1 = 1})