Przesyłanie strumieniowe wyników xml-conduit parse
Chcę użyćxml-conduit
, konkretnieText.XML.Stream.Parse
aby leniwie wyodrębnić listę obiektów z dużego pliku XML.
Jako przypadek testowy używamniedawno ponownie wydane zrzuty danych StackOverflow. Aby to było proste, zamierzam wyodrębnić wszystkie nazwy użytkowników zstackoverflow.com-Users.7z
. Nawet jeśli plik jest.7z
, file
mówi, że są to tylko dane skompresowane za pomocą bzip2 (na końcu pliku mogą być jakieś rzeczy 7zip, ale teraz mnie to nie obchodzi).
Uproszczona wersja XML byłaby
<users>
<row id="1" DisplayName="StackOverflow"/>
...
<row id="2597135" DisplayName="Uli Köhler"/>
...
</users>
Oparte nato poprzednie pytania i odpowiedzi i przykładna Hackage czytanie strumieniowe przykład XML w formie bz2-ed działa dla mnie doskonale
Jednak podczas używaniarunghc
aby uruchomić następujący program, działa bez drukowania jakichkolwiek danych wyjściowych:
{-# 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
Zakładam, że ten problem występuje, ponieważ Haskell próbuje głęboko ocenićusers
listę przed rozpoczęciem drukowania. Teoria ta jest wspierana przez wykorzystanie pamięci programu stale rosnące o 2 procent na sekundę (źródło: htop).
Jak mogę „przesyłać strumieniowo” wyniki na standardowe wyjście? Zakładam, że jest to możliwe, dodając kolejne oświadczenie dotyczące przewodu, takie jak$$ CB.sinkFile "output.txt"
na końcu. Ta konkretna wersja oczekuje jednakConduit
wyjście zByteString
. Czy mógłbyś wskazać mi właściwy kierunek, skąd stąd pójść?
Każda pomoc zostanie doceniona!