2012-02-12 3 views
4

http-conduitからの応答をxml-conduit経由でXML文書に変換しようとしています。http-conduitをxml-conduitに接続

doPost関数は、XMLドキュメントを取得してサーバーに送信します。サーバーはXML文書で応答します。

doPost queryDoc = do 
    runResourceT $ do 

     manager <- liftIO $ newManager def 
     req <- liftIO $ parseUrl hostname 

     let req2 = req 
       { method = H.methodPost 
       , requestHeaders = [(CI.mk $ fromString "Content-Type", fromString "text/xml" :: Ascii) :: Header] 
       , redirectCount = 0 
       , checkStatus = \_ _ -> Nothing 
       , requestBody = RequestBodyLBS $ (renderLBS def queryDoc) 
       } 

     res <- http req2 manager 
     return $ res 

以下の作品とリターン200 '':

let pingdoc = Document (Prologue [] Nothing []) (Element "SYSTEM" [] []) [] 
Response status headers body <- doPost pingdoc 
return (H.statusCode status) 

私がしようとxml-コンジットを使用して応答本体を解析する場合しかし、私は問題に実行:

Response status headers body <- doPost xmldoc 
let xmlRes' = parseLBS def body 

結果のコンパイルエラーは次のようになります。

Couldn't match expected type `L.ByteString' 
      with actual type `Source m0 ByteString' 
In the second argument of `parseLBS', namely `body' 
In the expression: parseLBS def body 
In an equation for `xmlRes'': xmlRes' = parseLBS def body 

$ =と$$を使ってhttp-conduitからxml-conduitにSourceを接続しようとしましたが、何の成功もありません。

私に正しい方向を指すヒントはありますか?前もって感謝します。

ニール

答えて

6

それは怠惰なByteStringを返すのではなくSourceようにするには、むしろhttpよりhttpLbsを使用することができます - それはそれは必要なものだからparseLBS機能の名前は:L B azy YTE S tring。しかし、あなたが言及したように、2つが直接に基づいているコンジットインターフェイスを使用するのがおそらく最も良いです。これは、XMLからSinkへのhttp-導管からSourceを接続し、XML-コンジットのsinkDoc機能を使用しています

xmlRes' <- runResourceT $ do 
    Response status headers body <- doPost xmldoc 
    body $$ sinkDoc def 

:これを行うには、doPostからrunResourceT行を削除し、XMLドキュメントを取得するには、以下を使用する必要があります-導管。

接続したら、runResourceTを使用してパイプライン全体を実行する必要があります。これにより、割り当てられたすべてのリソースがタイムリーに解放されます。元のコードの問題点は、遅いうちにResourceTが実行されていることです。内部はdoPostです。パイプラインは完全に単一のResourceTの範囲内で実行する必要があるため、実際に結果を出力したい時点でrunResourceTを使用してください。

ところで、res <- http req2 manager; return $ resはちょうどhttp req2 managerに簡略化することができます。

+0

マイナーな調整でうまくいきました。私はsinkDocの後にデフォルトの解析設定を追加しなければなりません: 'body $$ sinkDoc def'ありがとう! – Neil

関連する問題