[英]connecting http-conduit to xml-conduit
我正在努力通過xml-conduit將響應從http-conduit轉換為XML文檔。
doPost
函數接受XML Document並將其發布到服務器。 服務器使用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-conduit解析Response主體時,我遇到了問題:
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,但我沒有任何成功。
有沒有人有任何提示指出我正確的方向? 提前致謝。
尼爾
你可以使用httpLbs
而不是http
,這樣它就會返回一個懶惰的ByteString
而不是一個Source
- parseLBS
函數被命名,因為這就是它所需要的:一個L azy B yte S tring。 但是,正如您所提到的,最好使用兩者直接基於的管道接口。 為此,您應該從doPost
刪除runResourceT
行,並使用以下內容獲取XML文檔:
xmlRes' <- runResourceT $ do
Response status headers body <- doPost xmldoc
body $$ sinkDoc def
這使用xml-conduit的sinkDoc
函數,將來自http-conduit的Source
連接到xml-conduit的Sink
。
連接完成后,必須使用runResourceT
運行完整的管道,以確保及時釋放所有分配的資源。 你的原始代碼的問題是它從doPost
內部過早地運行ResourceT
; 您通常應該在想要實際結果的位置使用runResourceT
,因為管道必須完全在單個ResourceT
的范圍內運行。
順便說一句, res <- http req2 manager; return $ res
res <- http req2 manager; return $ res
可以簡化為http req2 manager
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.