Sno*_*ual 13 json haskell aeson
继上一篇文章之后,我发现自己完全陷入困境.我正在尝试将JSON结构解析为我自己的类型,而且我不仅坚持如何解析数组,我甚至不确定我是否按预期使用了Aeson库.任何帮助将不胜感激.
代码:
data Exif = Exif [(T.Text, ExifValue)] deriving (Show)
data ExifValue =
ExifText T.Text |
ExifInt Integer |
ExifDouble Double |
ExifBool Bool |
ExifArray [ExifValue]
deriving (Show)
instance FromJSON ExifValue where
parseJSON (Number (I n)) = return $ ExifInt n
parseJSON (Number (D n)) = return $ ExifDouble n
parseJSON (String s) = return $ ExifText s
parseJSON (Bool b) = return $ ExifBool b
-- parseJSON (Array a) = ?????
instance FromJSON Exif where
parseJSON (Object o) = do
x <- sequence $ map f (M.assocs o)
return $ Exif x
where
f (t, x) = do
y <- parseJSON x
return ((t, y) :: (T.Text, ExifValue))
parseExifFile = fmap parseExifData . B.readFile
parseExifData :: B.ByteString -> Data.Attoparsec.Result (Data.Aeson.Result [Exif])
parseExifData content = parse (fmap fromJSON json) content
Run Code Online (Sandbox Code Playgroud)
测试文件:
[{
"SourceFile": "test.jpg",
"ExifTool:ExifToolVersion": 8.61,
"File:FileName": "test.jpg",
"File:FileSize": 2174179,
"File:FileModifyDate": "2011:07:27 16:53:49-07:00",
"File:FilePermissions": 644,
"File:FileType": "JPEG",
"File:MIMEType": "image/jpeg",
"File:ExifByteOrder": "MM",
"File:CurrentIPTCDigest": "32d6a77098a73aa816f2570c9472735a",
"File:ImageWidth": 2592,
"File:ImageHeight": 1936,
"File:EncodingProcess": 0,
"File:BitsPerSample": 8,
"File:ColorComponents": 3,
"File:YCbCrSubSampling": "2 2",
"XMP:Subject": ["alpha","beta","gamma"]
}]
Run Code Online (Sandbox Code Playgroud)
acf*_*zer 11
你必须遵循parseJSON
一条兔子小道的类型,但一旦你认识到(Array a)
代表什么,它应该是直截了当的.
parseJSON
有类型Value -> Parser a
,所以(Array a)
有类型Value
.该类型中的一个变体Value
是Array Array
,因此a
in (Array a)
必须是类型Array
,定义为Vector Value
.在Value
里面,且s Vector
是要叫什么parseJSON
就来回报您的清单,因此,请检查您可以用做什么Vector
.
最简单的方法可能是转换a
为一个列表Vector.toList
,然后mapM
用来解析Values
.
或者,您可以Vector
通过将ExifArray
变体更改为保持Vector ExifValue
,然后使用来避免列表转换Vector.mapM
.
我不是母语为英语的人,所以我可能不太了解你.我想你想知道如何将json解析为递归数据类型,就像ExifValue
你提出的那样.所以我做了一个简单的例子来展示如何将json解析为递归数据类型.
{-# LANGUAGE OverloadedStrings #-}
import qualified Data.ByteString as B
import Data.Maybe
import Control.Monad
import Control.Applicative
import Data.Attoparsec
import Data.Attoparsec.Number
import Data.Aeson
import qualified Data.Vector as V
data Data = D1 Int | D2 [Data]
deriving (Show)
instance FromJSON Data where
parseJSON (Number (I n)) = return $ D1 $ fromInteger n
parseJSON (Array a) = D2 <$> mapM parseJSON (V.toList a)
main = do
let v = fromJust $ maybeResult $ parse json "[1,2,3,[5,3,[6,3,5]]]"
let v1 :: Data
v1 = case fromJSON v of
Success a -> a
Error s -> error s
print v1
Run Code Online (Sandbox Code Playgroud)