Closed slyrus closed 3 years ago
Thanks a lot!
It really works. But why? :D I couldn't figure out yet ...
In my solution, I use a helper variable consumed
to remember whether a tag was read
(that is when the :start-element had the name "sheet"
(defun sheets (xlsx)
"Return sheet informations as list of lists (sheet-name sheet-number sheet-address)."
(klacks:with-open-source (src (source-entry "xl/workbook.xml" xlsx))
(loop :for key = (klacks:peek src)
:for consumed = nil
:while key
:nconcing (case key
(:start-element
(let ((tag-name (klacks:current-qname src)))
(cond ((equal tag-name "sheet")
(setf consumed t)
(list (let* ((sax (klacks:serialize-element src (cxml-xmls:make-xmls-builder)))
(attributes (cadr sax)))
(list (cadr (assoc "name" attributes :test #'equal))
(parse-integer (cadr (assoc "sheetId" attributes :test #'equal)))
(concatenate 'string "xl/worksheets/sheet"
(cadr (assoc "sheetId" attributes :test #'equal))
".xml")))))
(t nil))))
(otherwise nil))
:do (unless consumed
(klacks:consume src)))))
In case it was consumed, the klacks:serialize-element
already consumed until end of the "sheet" tag.
Therefore the consuming must be suppressed.
However, I don't understand why your code
(defun sheets-new (xlsx)
"Return sheet informations as list of lists (sheet-name sheet-number sheet-address)."
(klacks:with-open-source (src (source-entry "xl/workbook.xml" xlsx))
(loop :for key = (klacks:peek src)
:while key
:nconc (if (and (eql key :start-element)
(equal (klacks:current-qname src) "sheet"))
(list (let* ((sax (klacks:serialize-element src (cxml-xmls:make-xmls-builder)))
(attributes (cadr sax)))
(list (cadr (assoc "name" attributes :test #'equal))
(parse-integer (cadr (assoc "sheetId" attributes :test #'equal)))
(concatenate 'string
"xl/worksheets/sheet"
(cadr (assoc "sheetId" attributes :test #'equal))
".xml"))))
(progn
(klacks:consume src)
nil)))))
is equivalent to mine ...
Can you explain how your code works?
else
-branch and returning of nil
is also put there - so you need the progn
.
thanks.
No need for consumed
helper variable ...
You (or I) can close this but this seemed like a simpler solution to your fix to #2 .