Esempio di come analizzare exiftool uscita JSON in Haskell
Domanda
Non riesco a dare un senso a qualsiasi della documentazione. Qualcuno può fornire un esempio di come posso analizzare il seguente output exiftool
accorciato utilizzando il modulo Text.JSON
Haskell? I dati vengono generando usando il comando 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
}]
Soluzione
Bene, il modo più semplice è quello di ottenere indietro un JSValue dal JSON pacchetto, come così (supponendo che i dati sono in text.json):
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))]})])
questo solo ti dà un JSON Haskell tipo di dati generico.
Il prossimo passo sarà quello di definire un tipo di dati Haskell personalizzati per i dati, e scrivere un'istanza di JSON per questo, che converte tra JSValue di cui sopra, e il tipo.
Altri suggerimenti
Grazie a tutti. Da vostri suggerimenti sono stato in grado di mettere insieme i seguenti che traduce il JSON di nuovo in coppie nome-valore.
data Exif =
Exif [(String, String)]
deriving (Eq, Ord, Show)
instance JSON Exif where
showJSON (Exif xs) = showJSONs xs
readJSON (JSObject obj) = Ok $ Exif [(n, s v) | (n, JSString v) <- o]
where
o = fromJSObject obj
s = fromJSString
Purtroppo, sembra che la libreria non è in grado di tradurre il JSON subito indietro in una semplice struttura dati Haskell. In Python, è una battuta: json.loads(s)
.