An example of how to parse JSON output of exiftool in Haskell

I can not understand any documentation. Can someone provide an example of how I can exiftool following abbreviated exiftool output using the Haskell Text.JSON module? Data is generated using the exiftool -G -j <files.jpg> .

 [{ "SourceFile": "DSC00690.JPG", "ExifTool:ExifToolVersion": 7.82, "File:FileName": "DSC00690.JPG", "Composite:LightValue": 11.6 }, { "SourceFile": "DSC00693.JPG", "ExifTool:ExifToolVersion": 7.82, "File:FileName": "DSC00693.JPG", "EXIF:Compression": "JPEG (old-style)", "EXIF:ThumbnailLength": 4817, "Composite:LightValue": 13.0 }, { "SourceFile": "DSC00694.JPG", "ExifTool:ExifToolVersion": 7.82, "File:FileName": "DSC00694.JPG", "Composite:LightValue": 3.7 }] 
+4
source share
2 answers

Well, the easiest way is to return JSValue from the json package, for example (if your data is in .json text):

 Prelude Text.JSON> s <- readFile "test.json" Prelude Text.JSON> decode s :: Result JSValue Ok (JSArray [JSObject (JSONObject {fromJSObject = [("SourceFile",JSString (JSONString {fromJSString = "DSC00690.JPG"})),("ExifTool:ExifToolVersion",JSRational False (391 % 50)),("File:FileName",JSString (JSONString {fromJSString = "DSC00690.JPG"})),("Composite:LightValue",JSRational False (58 % 5))]}),JSObject (JSONObject {fromJSObject = [("SourceFile",JSString (JSONString {fromJSString = "DSC00693.JPG"})),("ExifTool:ExifToolVersion",JSRational False (391 % 50)),("File:FileName",JSString (JSONString {fromJSString = "DSC00693.JPG"})),("EXIF:Compression",JSString (JSONString {fromJSString = "JPEG (old-style)"})),("EXIF:ThumbnailLength",JSRational False (4817 % 1)),("Composite:LightValue",JSRational False (13 % 1))]}),JSObject (JSONObject {fromJSObject = [("SourceFile",JSString (JSONString {fromJSString = "DSC00694.JPG"})),("ExifTool:ExifToolVersion",JSRational False (391 % 50)),("File:FileName",JSString (JSONString {fromJSString = "DSC00694.JPG"})),("Composite:LightValue",JSRational False (37 % 10))]})]) 

it just gives you the json Haskell generic data type.

The next step is to define a Haskell user-defined data type for your data and write a JSON instance for it that converts JSValue as above and your type.

+10
source

Thanks to everyone. From your suggestions, I was able to compile the following, which translates JSON back into name-value pairs.

 data Exif = Exif [(String, String)] deriving (Eq, Ord, Show) instance JSON Exif where showJSON (Exif xs) = showJSONs xs readJSON (JSObject obj) = Ok $ Exif [(n, sv) | (n, JSString v) <- o] where o = fromJSObject obj s = fromJSString 

Unfortunately, it looks like the library cannot translate JSON directly into a simple Haskell data structure. In Python, this is single-line: json.loads(s) .

+2
source

All Articles