(ql:quickload :lquery) (defun parse-side (node) (list :done (string= "true" (or (plump:attribute node "Completed") "false")) :berries (parse-integer (or (plump:attribute node "TotalStrawberries") "0")) :deaths (parse-integer (or (plump:attribute node "Deaths") "0")) :time (/ (parse-integer (or (plump:attribute node "BestTime") "0")) 1000.0) :checkpoints (length (lquery:$ node "Checkpoints" "string")))) (defun parse-area (node) (let ((sides (lquery:$ node "AreaModeStats" (map #'parse-side)))) (list :id (parse-integer (plump:attribute node "ID")) :time (loop for side across sides sum (getf side :time)) :berries (loop for side across sides sum (getf side :berries)) :deaths (loop for side across sides sum (getf side :deaths)) :sides sides))) (defun parse-save (file) (let* ((plump:*tag-dispatchers* plump:*xml-tags*) (save (lquery:$1 (initialize file) "SaveData"))) (list :done NIL :started NIL :berries (parse-integer (lquery:$1 save "TotalStrawberries" (text))) :deaths (parse-integer (lquery:$1 save "TotalDeaths" (text))) :time (/ (parse-integer (lquery:$1 save "CurrentSession" (attr "Time"))) 1000.0) :areas (lquery:$ save "Areas AreaStats" (map #'parse-area)))))