-->

容错JSON解析(Fault tolerant JSON parsing)

2019-07-29 09:46发布

我使用Data.Aeson解析一些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

我要补充一点,我使用deriveJSON从Data.Aeson.TH生成解析代码。 如果我写的FromJSON代码手动它的容错,但我想没有这样做...

Answer 1:

如果你正在使用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

运行此会失败,TH派生的实例由于“场2”的记录不存在。 在Generic情况下返回所需的结果:

Just (MyRecord {field1 = 1})


文章来源: Fault tolerant JSON parsing