json - 容错 JSON 解析

标签 json haskell aeson

我正在使用 Data.Aeson 将一些 JSON 解析为 Record 类型。不时将数据添加到 JSON 中,这会破坏我的代码,因为 Aeson 会提示以下内容:

expected Object with 21 name/value pairs but got 23 name/value



我真的更喜欢以容错的方式解析 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 的 derivedJSON 来生成解析代码。如果我手动编写 FromJSON 代码,它是容错的,但我不想这样做......

最佳答案

如果您使用 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})

关于json - 容错 JSON 解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10604808/

相关文章:

json - 是否可以使用 nginx 合并两个 json 响应?

jquery - 可选 NFC 登录到基于 Web 的系统

haskell - 在 Powershell 中运行这段 Haskell 代码什么都不做

string - 自定义数据类型的显示列表实例

haskell - 在 aeson 的解析器中收集对象的所有未使用字段的更好方法?

json - Aeson如何使用Data.Text.Lazy.IO解析JSON文件

ruby-on-rails - 通过 HTTP、Ruby(无 ROR)序列化/反序列化对象

json - 使用 knockout.mapping 时,knockoutjs 抛出 "Unknown template value"

haskell - 如何混合应用仿函数和箭头

json - 带有 Aeson 的任意 JSON 键 - Haskell