使用HXT避免空间泄漏读取HTML文档

时间:2010-09-04 19:13:36

标签: html xml haskell html-parsing

Link to truncated version of example document

我正在尝试在最后一个“pre”中提取大块文本,处理它并输出它。 出于争论的目的,假设我想申请

concatMap (unwords . take 62 . drop 11) . lines

到文本并输出。

当我这样做时,这会占用4M html文档上超过400M的空间。

我所拥有的代码非常简单,因此我不会将其包含在内,因为担心会产生偏差。
这是代码的一次迭代:

file = readDocument [(a_validate, v_0), (a_parse_html, v_1)] "Cache entry information.xhtml"
text = fmap last $ runX $
  file >>>
  deep (hasName "pre") />
  isText >>>
--  changeText (unwords . take 62 . drop 11 . lines) >>>
  getText

我认为问题在于我正在这样做,HXT试图在读取内容时将所有文本保存在内存中。

根据this 看起来HXT至少需要读取整个文档,尽管不要将其存储在内存中。

我将尝试其他解析器HaXmL,成为下一个解析器 注:我已经通过将输入文件视为纯文本和由"<pre>00000000:""</pre></body>\n</html>"

分隔的所需部分解决了初始问题

2 个答案:

答案 0 :(得分:1)

HXT的解析器是“在线”解析器吗?

你所拥有的例子适用于String,前提是每一行都不是病态的:

unwords . take 62 . drop 11 . lines

在这里,您只会消耗73行输入,11个您丢弃的输入和62个您操作的输入。但是,该示例与XML处理大多无关。如果HXT的解析器不是在线解析器,则必须先将整个文件读入内存,然后才能对任何嵌入的字符串数据进行操作。

我担心HXT是否是一个在线解析器,但这似乎是你问题的症结所在。

答案 1 :(得分:0)

尝试使用模块ByteString的{​​{1}}。通常的字符串针对递归进行了优化,并且在大量数据的情况下表现非常糟糕。此外,您可以尝试使您的函数更严格(例如,使用Data.Bytestring.Lazy),以避免由于未评估的thunk而导致的大量开销。但要小心,因为如果应用错误,这可能会使事情变得更糟。

PS:提供一个简短的例子是总是一个好主意。