容错JSON解析 [英] Fault tolerant JSON parsing
问题描述
我使用Data.Aeson将一些JSON解析为Record类型。有时候数据会被添加到JSON中,这会破坏我的代码,因为Aeson会抱怨以下几点:
期望的对象与21
名称/值对,但得到23名称/值
我真的更喜欢解析容错的JSON方式 - 我不关心是否有更多的字段在以后添加到JSON中,只是解析任何你可以!有没有办法实现这种容错?这是我的代码:
myRecordFromJSONString :: BS.ByteString - >也许MyRecord
myRecordFromJSONString s = case Data.Attoparsec.parse $ b $ j的完成_rest res - > Data.Aeson.Types.parseMaybe parseJSON res
_ - > Nothing
我应该补充说我使用Data.Aeson.TH中的deriveJSON来生成解析代码。如果我手动编写FromJSON代码,它是容错的,但我不想那样做......
如果我手动编写FromJSON代码您正在使用GHC 7.2或7.4, aeson
中的新仿制支持不检查额外字段。
$ b
{ - #LANGUAGE DeriveGeneric # - }
{ - #LANGUAGE OverloadedStrings# - }
导入Data.Aeson
导入限定的Data.Aeson.Types
导入Data.Attoparsec
导入合格的Data.ByteString作为BS
import Data.ByteString.Char8()
import GHC.Generics
data MyRecord = MyRecord
{field1 :: Int
}派生(Generic,Show)
实例FromJSON MyRecord
myRecordFromJSONString :: BS.ByteString - >也许MyRecord
myRecordFromJSONString s = case Data.Attoparsec.parse $ b $ j的完成_rest res - > Data.Aeson.Types.parseMaybe parseJSON res
_ - > Nothing
main :: IO()
main = do
let parsed = myRecordFromJSONString{\field1 \:1,\field2 \: 2}
print parsed
运行这个会导致TH派生实例失败, field2'不存在于记录中。 Generic
实例返回所需的结果:
Just(MyRecord {field1 = 1})
I'm using Data.Aeson to parse some JSON into a Record type. From time to time data is added to the JSON and this breaks my code as Aeson complains something to the effect of:
expected Object with 21 name/value pairs but got 23 name/value
I'd really prefer to parse the JSON in a fault tolerant way -- I don't care if more fields are added to the JSON at a later date, just parse whatever you can! Is there a way to achieve this fault tolerance? Here's my code:
myRecordFromJSONString :: BS.ByteString -> Maybe MyRecord
myRecordFromJSONString s = case Data.Attoparsec.parse json s of
Done _rest res -> Data.Aeson.Types.parseMaybe parseJSON res
_ -> Nothing
I should add that I'm using deriveJSON from Data.Aeson.TH to generate the parsing code. If I write the FromJSON code manually it's fault tolerant but I'd like to not have to do that...
If you are using GHC 7.2 or 7.4, the new generics support in aeson
doesn't check for extra fields. I'm not sure if this is by design or not but we use it for the same reason.
{-# 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
Running this would fail with the TH derived instance due to 'field2' not existing in the record. The Generic
instance returns the desired result:
Just (MyRecord {field1 = 1})
这篇关于容错JSON解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!