?

Log in

clojure и XML transformation - Оживший юзерпик

Mar. 4th, 2013

08:00 pm - clojure и XML transformation

Previous Entry Share Next Entry

Попробовал zippers. Задача — поменять все <delta value="XXX"> на <delta value="0">:

(defn- zero-deltas [zip]
  (loop [loc zip]
    (if (zip/end? loc)
      loc
    (recur (zip/next (if (= (:tag (zip/node loc)) :delta)
   	                 (zip/edit loc #(assoc-in % [:attrs :value] "0"))
                         loc))))))

Всё хорошо, но непонятно, что можно вернуть из функции, чтобы можно было аналогичную звать дальшe:
(-> filename parse xml-zip 
    zero-deltas
    something-else)

Переписал на data.xml с рекурсивным беганием map-ами по :content. Омерзительно. В недоумении.

Upd: слава аллаху опенсорсу, я таки посмотрел в исходники clojure.zip. Они держат сопутствующие структуры в метаданных. Убиться веником.

Upd2: работает вот так, но недоумение остаётся:
  (if (zip/end? loc)
      (with-meta (vector (zip/root loc) nil) (meta zip))

Comments:

[User Picture]
From:rblaze
Date:March 4th, 2013 07:11 pm (UTC)
(Link)
Фу, сколько скобочек.
(Reply) (Thread)
[User Picture]
From:zinal
Date:March 4th, 2013 07:44 pm (UTC)
(Link)
Хм... не знаток ни Closure, ни zippers, но тут же явно побочный эффект используется. Т.е. модифицируется исходное XML-дерево, переданное как аргумент (результат вызова функции разбора документа). Значит, достаточно запомнить первоначальный аргумент, с которым вызывается zero-deltas, и вернуть его из zero-deltas. Возможно, понадобится промежуточное замыкание (для хранения ссылки на исходное дерево).
(Reply) (Thread)
[User Picture]
From:tobotras
Date:March 5th, 2013 01:15 am (UTC)
(Link)
Не, здесь функции чистые, так что вернуть надо именно модифицированное дерево. А у зиппера location, когда доходит до (end?), теряет всякий смысл, вроде.
(Reply) (Parent) (Thread)
[User Picture]
From:zinal
Date:March 5th, 2013 05:48 pm (UTC)
(Link)
Хм.. тот самый случай, когда чистые функции дают более корявый код по сравнению с возможным вариантом, использующим побочные эффекты - при всех его недостатках.
Найденное решение (Update2) выглядит как минимум странно, и может сломаться при смене версии zippers.
(Reply) (Parent) (Thread)