Contoh cara mengurai keluaran Exiftool JSON di Haskell

Saya tidak dapat memahami dokumentasi apa pun. Dapatkah seseorang memberikan contoh bagaimana saya dapat mengurai keluaran exiftool singkat berikut menggunakan modul Haskell Text.JSON? Data dihasilkan menggunakan perintah 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
}]

person me2    schedule 18.01.2010    source sumber


Jawaban (2)


Nah, cara termudah adalah mendapatkan kembali JSValue dari paket json, seperti itu (dengan asumsi data Anda ada di 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))]})])

ini hanya memberi Anda tipe data json Haskell generik.

Langkah selanjutnya adalah menentukan tipe data Haskell khusus untuk data Anda, dan menulis sebuah instance JSON untuk itu, yang mengkonversi antara JSValue seperti di atas, dan tipe Anda.

person Don Stewart    schedule 18.01.2010
comment
Saya awalnya memposting jawaban terpisah pada waktu yang sama, tetapi saya merasa saya lebih menyukai kata-kata yang satu ini... Oh baiklah. Saya hanya akan menambahkan €0,02 saya sebagai komentar: lihat file Text/JSON.hs di sumber json-the-package. Ada banyak contoh JSON sederhana yang didefinisikan di sana dan dapat menjadi contoh yang berguna. - person Michał Marczyk; 19.01.2010
comment
Jawaban bagus! Dan sekali lagi saya berharap tidak kurang dari rekan penulis 'Real World Haskell' (book.realworldhaskell.org). Itu buku yang sangat keren btw. - person Robert Massaioli; 24.05.2010
comment
Untuk pemula, Anda harus melakukan Prelude>:m +Text.JSON ...sebelum menjalankan baris dalam respons don. - person ramanujan; 12.12.2010

Terimakasih untuk semua. Dari saran Anda, saya dapat mengumpulkan yang berikut ini yang menerjemahkan JSON kembali menjadi pasangan nama-nilai.

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

Sayangnya, tampaknya perpustakaan tidak dapat menerjemahkan JSON kembali ke struktur data Haskell yang sederhana. Dalam Python, ini adalah satu baris: json.loads(s).

person me2    schedule 19.01.2010
comment
Ya, itu harus diketik secara statis. Jadi Haskell membuat tipe JSValue sederhana -- yang dapat Anda gunakan secara langsung jika diinginkan. Manfaat menggunakan Haskell adalah pemeriksaan statis ekstra yang akan Anda dapatkan jika Anda membangun struktur tertentu. - person Don Stewart; 19.01.2010