Haskell,Aeson& JSON解析为自定义类型 [英] Haskell, Aeson & JSON parsing into custom type
问题描述
继上一篇文章之后,我发现我完全卡住了。我试图将JSON结构解析为我自己的类型,不仅我坚持如何解析数组,我甚至不确定是否按照预期使用了Aeson库。任何帮助将不胜感激。
代码:
数据Exif = Exif [(T.Text,ExifValue)]派生(显示)
数据ExifValue =
ExifText T.Text |
ExifInt Integer |
ExifDouble Double |
ExifBool Bool |
ExifArray [ExifValue]
deriving(显示)
实例FromJSON ExifValue其中
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 )= ?????
实例FromJSON Exif其中
parseJSON(Object o)= do
x< - sequence $ map f(M.assocs o)
return $ Exif x
其中
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
测试文件:
[{
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,
文件: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]
}]
一点点d拥有一条兔子踪迹,但一旦你认识到(Array a)
表示,它应该是直截了当的。
parseJSON
有类型值 - >解析器a
,所以(Array a)
具有类型值
。Value中的一个变体是
Array Array
,所以a $
。(Array a)
中的c $ c>必须是Array
类型,它定义为矢量值
。Vector
中的Value
s是您要调用的内容parseJSON
on返回你的列表,所以看看你可以用Vector
。 p
最简单的方法可能是将
a
转换为Vector.toList
列表,然后使用mapM
值
或者,您可以避免
Vector
通过更改您的ExifArray
变体以保存Vector ExifValue
,然后使用Vector.mapM
。Following on from a previous post, I've found I'm totally stuck. I'm trying to parse a JSON structure into my own type, and not only am I stuck on how to parse the Array, I'm not even sure if I'm using the Aeson library as intended. Any help would be greatly appreciated.
The code:
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
The test file:
[{ "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"] }]
解决方案You have to follow the type of
parseJSON
a little bit down a rabbit trail, but once you recognize what(Array a)
represents, it should be straightforward.
parseJSON
has typeValue -> Parser a
, so(Array a)
has typeValue
. One of the variants in theValue
type isArray Array
, so thea
in(Array a)
must be of the typeArray
, which is defined asVector Value
. TheValue
s inside thatVector
are what you want to callparseJSON
on to return your list, so check out what you can do with aVector
.The easiest approach would probably to convert
a
to a list withVector.toList
, and then usemapM
to parse theValues
.Alternately, you could avoid the
Vector
to list conversion by changing yourExifArray
variant to holdVector ExifValue
, and then usingVector.mapM
.这篇关于Haskell,Aeson& JSON解析为自定义类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文