Ejemplo de cómo analizar exiftool salida JSON en Haskell
Pregunta
No puedo dar sentido a cualquiera de la documentación. Por favor alguien puede proporcionar un ejemplo de cómo se puede analizar la siguiente salida exiftool
abreviada utilizando el módulo Text.JSON
Haskell? Los datos se genera usando el exiftool -G -j <files.jpg>
comando.
[{
"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
}]
Solución
Bueno, la forma más fácil es volver un JSValue de la JSON paquete, al igual por lo que (suponiendo que sus datos están en 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))]})])
Esto sólo te da una JSON genérica Haskell tipo de datos.
El siguiente paso será definir una costumbre Haskell tipo de datos para los datos, y escribir una instancia de JSON para eso, que convierte entre JSValue de que el anterior, y su tipo.
Otros consejos
Gracias a todos. A partir de sus sugerencias yo era capaz de reunir los siguientes elementos que traduce el JSON de nuevo en pares nombre-valor.
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
Por desgracia, parece que la biblioteca no es capaz de traducir el JSON hacia atrás en una sencilla estructura de datos Haskell. En Python, es una de una sola línea: json.loads(s)
.