Потоковые результаты анализа xml -роводника
Я хочу использоватьxml-conduit
конкретноText.XML.Stream.Parse
чтобы лениво извлечь список объектов из большого файла XML.
В качестве теста я используюнедавно переизданные дампы данных StackOverflow, Чтобы было проще, я собираюсь извлечь все имена пользователей изstackoverflow.com-Users.7z
, Даже если файл.7z
, file
говорит, что это просто сжатые bzip2 данные (в конце файла может быть что-то вроде 7zip, но сейчас мне все равно).
Упрощенная версия XML будет
<users>
<row id="1" DisplayName="StackOverflow"/>
...
<row id="2597135" DisplayName="Uli Köhler"/>
...
</users>
На основеэтот предыдущий Q & A и примерна Hackage потоковое чтение примера XML в форме bz2 отлично работает для меня
Однако при использованииrunghc
чтобы запустить следующую программу, она запускается без вывода какого-либо вывода:
{-# LANGUAGE OverloadedStrings #-}
import Data.Conduit (runResourceT, ($), ($=))
import qualified Data.Conduit.Binary as CB
import Data.Conduit.BZlib
import Data.Conduit
import Data.Text (Text)
import System.IO
import Text.XML.Stream.Parse
import Control.Applicative ((<*))
data User = User {name :: Text} deriving (Show)
parseUserRow = tagName "row" (requireAttr "DisplayName" <* ignoreAttrs) $ \displayName -> do
return $ User displayName
parseUsers = tagNoAttr "users" $ many parseUserRow
main = do
users <- runResourceT $ CB.sourceFile "stackoverflow.com-Users.7z" $= bunzip2 $= parseBytes def $ force "users required" parseUsers
putStrLn $ unlines $ map show users
Я предполагаю, что эта проблема возникает из-за того, что Haskell пытается глубоко оценитьusers
список, прежде чем начать печатать его. Эта теория поддерживается использованием памяти программы, постоянно растущей примерно на 2 процента в секунду (источник: htop).
Как я могу транслировать результаты в stdout? Я предполагаю, что это возможно, добавив еще один оператор канала, как$$ CB.sinkFile "output.txt"
в конце. Эта конкретная версия, однако, ожидаетConduit
выводByteString
, Не могли бы вы указать мне правильное направление, куда идти отсюда?
Любая помощь будет оценена!