3

以下问题基于此问题的公认答案。接受答案的作者说,流式帮助程序 APIxml-conduit多年来没有更新(来源:SO question 的接受答案),他推荐该Cursor接口。

基于第一个问题的解决方案,我编写了以下使用包Cursor接口的haskell代码xml-conduit

import Text.XML as XML (readFile, def)
import Text.XML.Cursor (Cursor, ($/), (&/), ($//), (>=>), 
    fromDocument, element, content)
import Data.Monoid (mconcat)
import Filesystem.Path (FilePath)
import Filesystem.Path.CurrentOS (fromText)

data Page = Page
    { title :: Text
    } deriving (Show)

parse :: FilePath -> IO ()
parse path = do
    doc <- XML.readFile def path
    let cursor = fromDocument doc
    let pages = cursor $// element "page" >=> parseTitle
    writeFile "output.txt" ""
    mapM_ ((appendFile "output.txt") . (\x -> x ++ "\n") . show) pages

parseTitle :: Cursor -> [Page]
parseTitle c = do
    let titleText = c $/ element "title" &/ content
    [Page (mconcat titleText)]

main :: IO ()
main = parse (fromText "input.xml")

此代码适用于小型 XML 文件。但是,当代码在 30G XML 文件上运行时,执行会被操作系统终止。

如何使此代码在非常大的 XML 文件上工作?

4

1 回答 1

1

Cursor模块要求整个内容都在内存中,这在这种情况下似乎是不可能的。如果要处理那么大的文件,则需要使用流接口。

于 2015-04-05T12:21:42.730 回答