我正在编写一个Clojure库来解析Mac OS X的基于XML的property list files。代码工作正常,除非你给它一个大的输入文件,在这一点你得到java.lang.OutOfMemoryError: Java heap space
。同一个多方法的不同方法之间的递归
下面是一个例子输入文件(足够小,做工精细):
<plist version="1.0">
<dict>
<key>Integer example</key>
<integer>5</integer>
<key>Array example</key>
<array>
<integer>2</integer>
<real>3.14159</real>
</array>
<key>Dictionary example</key>
<dict>
<key>Number</key>
<integer>8675309</integer>
</dict>
</dict>
</plist>
clojure.xml/parse
变成这样:
{:tag :plist, :attrs {:version "1.0"}, :content [
{:tag :dict, :attrs nil, :content [
{:tag :key, :attrs nil, :content ["Integer example"]}
{:tag :integer, :attrs nil, :content ["5"]}
{:tag :key, :attrs nil, :content ["Array example"]}
{:tag :array, :attrs nil, :content [
{:tag :integer, :attrs nil, :content ["2"]}
{:tag :real, :attrs nil, :content ["3.14159"]}
]}
{:tag :key, :attrs nil, :content ["Dictionary example"]}
{:tag :dict, :attrs nil, :content [
{:tag :key, :attrs nil, :content ["Number"]}
{:tag :integer, :attrs nil, :content ["8675309"]}
]}
]}
]}
我的代码变成Clojure的数据结构
{"Dictionary example" {"Number" 8675309},
"Array example" [2 3.14159],
"Integer example" 5}
这
我的代码的相关部分看起来像
; extract the content contained within e.g. <integer>...</integer>
(defn- first-content
[c]
(first (c :content)))
; return a parsed version of the given tag
(defmulti content (fn [c] (c :tag)))
(defmethod content :array
[c]
(apply vector (for [item (c :content)] (content item))))
(defmethod content :dict
[c]
(apply hash-map (for [item (c :content)] (content item))))
(defmethod content :integer
[c]
(Long. (first-content c)))
(defmethod content :key
[c]
(first-content c))
(defmethod content :real
[c]
(Double. (first-content c)))
; take a java.io.File (or similar) and return the parsed version
(defn parse-plist
[source]
(content (first-content (clojure.xml/parse source))))
代码的肉是content
函数,该函数是一个派生在:tag(XML标记的名称)上的多方法。我想知道是否有什么不同,我应该做的,以使这种递归更好。我试图用trampoline content
替换所有三个电话content
,但那不起作用。我应该怎么做才能让这种相互递归更高效地工作?或者我采取了一个根本错误的方法?
编辑:顺便说一句,这个代码是available on GitHub,在这种形式可能更容易玩弄。
我还没有听说过xml-zip,但我会研究它。谢谢! – bdesham 2011-02-03 19:18:36