将http-conduit连接到xml-conduit [英] connecting http-conduit to xml-conduit
问题描述
doPost $ c
doPost queryDoc = do
runResourceT $ do
manager< - liftIO $ newManager def
req< - liftIO $ parseUrl hostname
let req2 = req
{method = H.methodPost
,requestHeaders = [(CI.mk $ fromStringContent-Type,fromStringtext / xml:: Ascii):: Header]
,redirectCount = 0
,checkStatus = \ _ _ - > Nothing
,requestBody = RequestBodyLBS $(renderLBS def queryDoc)
}
res< - http req2 manager
return $ res
$ b以下工作并返回'200':
let pingdoc = Document(Prologue [] Nothing [])(ElementSYSTEM[] [])[]
响应状态标头正文< - doPost pingdoc
return(H.statusCode状态)
但是,当我尝试使用xml-conduit解析Response主体时,遇到问题:
响应状态标头正文< - doPost xmldoc
let xmlRes'= parseLBS def body
产生的编译错误是:
pre code $>无法匹配预期的类型`L.ByteString'
,其实际类型为'Source m0 ByteString'
在`parseLBS'的第二个参数中,即`body'
在表达式:parseLBS def body
在'xmlRes'方程中:xmlRes'= parseLBS def body
我试过连接使用$ =和$ $$来源于http-conduit到xml-conduit,但我没有任何成功。
有没有人有任何提示指向我在正确的方向?
Neil
您可以使用 httpLbs
而不是 http
,所以它会返回一个懒惰的 ByteString
比来源
- parseLBS
函数被命名,因为它是这样做的:a L azy b B s t s tring。但是,正如你所提到的那样,最好使用两者直接基于的导管接口。为此,您应该从 doPost
中删除 runResourceT
行,并使用以下命令获取XML文档:
xmlRes'< - runResourceT $ do
响应状态标头正文< - doPost xmldoc
body $ $ sinkDoc def
它使用xml-conduit的 sinkDoc
函数,将来自http-conduit的 Source
连接到xml-conduit的 Sink
。
连接后,完整的管道必须使用 runResourceT
,这可以确保及时发布所有分配的资源。原始代码的问题在于它太早从 doPost
中运行 ResourceT
;您通常应该使用 runResourceT
,因为流水线必须完全在单个 ResourceT范围内运行。
顺便说一下, res< - http req2 manager;返回$ res
可以简化为 http req2 manager
。
I'm struggling converting a Response from http-conduit to an XML document via xml-conduit.
The doPost
function takes an XML Document and posts it to the server. The server responds with an XML Document.
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
The following works and returns '200':
let pingdoc = Document (Prologue [] Nothing []) (Element "SYSTEM" [] []) []
Response status headers body <- doPost pingdoc
return (H.statusCode status)
However, when I try and parse the Response body using xml-conduit, I run into problems:
Response status headers body <- doPost xmldoc
let xmlRes' = parseLBS def body
The resulting compilation error is:
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
I've tried connecting the Source from http-conduit to the xml-conduit using $= and $$, but I'm not having any success.
Does anyone have any hints to point me in the right direction? Thanks in advance.
Neil
You could use httpLbs
rather than http
, so that it returns a lazy ByteString
rather than a Source
— the parseLBS
function is named because that's what it takes: a Lazy ByteString. However, it's probably best to use the conduit interface that the two are based on directly, as you mentioned. To do this, you should remove the runResourceT
line from doPost
, and use the following to get an XML document:
xmlRes' <- runResourceT $ do
Response status headers body <- doPost xmldoc
body $$ sinkDoc def
This uses xml-conduit's sinkDoc
function, connecting the Source
from http-conduit to the Sink
from xml-conduit.
Once they're connected, the complete pipeline has to be run using runResourceT
, which ensures all allocated resources are released in a timely fashion. The problem with your original code is that it runs the ResourceT
too early, from inside doPost
; you should generally use runResourceT
right at the point that you want an actual result out, because a pipeline has to run entirely within the scope of a single ResourceT
.
By the way, res <- http req2 manager; return $ res
can be simplified to just http req2 manager
.
这篇关于将http-conduit连接到xml-conduit的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!