我正在尝试从 xml 文件中提取标签并根据属性将每个标签写入单独的文件。
提取部分并不难:
*Main> ifs <- runX ( readDocument [withCurl [],withExpat yes] "file.xml" >>> getElement "TagName" >>> getAttrValue "Name" &&& this)
*Main> :t ifs
ifs :: [(String, XmlTree)]
我试图将 writeDocument 映射到第二个条目,但没有成功。我知道我必须以某种方式将它放回 IO Monad ......但不知道如何实现这一点。
出于测试目的,我从结果中提取了这些 XmlTrees:
*Main> let x = (map snd ifs) !! 0
*Main> :t x
x :: XmlTree
我可以像这样运行箭头x
:
*Main> runLA (getName) x
["TagName"]
但是当我尝试将它写入文件时,我收到错误消息,表明我不在 IO Monade 中(我认为):
*Main> runLA (writeDocument [] "test.xml") x
<interactive>:1:8:
Couldn't match expected type `LA a0 b0'
with actual type `IOSLA (XIOState s0) XmlTree XmlTree'
Expected type: LA a0 b0
Actual type: IOStateArrow s0 XmlTree XmlTree
In the return type of a call of `writeDocument'
In the first argument of `runLA', namely
`(writeDocument [] "test.xml")'
更改runLA
为runIOSLA
无济于事:
*Main> runIOSLA (writeDocument [] "test.xml") x
<interactive>:1:40:
Couldn't match expected type `XIOState s0'
with actual type `Data.Tree.NTree.TypeDefs.NTree XNode'
Expected type: XIOState s0
Actual type: XmlTree
In the second argument of `runIOSLA', namely `x'
In the expression: runIOSLA (writeDocument [] "test.xml") x
这是我所能得到的。
更新
正如 Travis Brown 指出的那样,可以在一个箭头中做到这一点:
runX . applyA $ readDocument [withCurl [],withExpat yes] "file.xml" >>> getElement "Tag" >>> getAttrValue "DEF" &&& this >>> arr (\ (n,x) -> root [] [constA x] >>> writeDocument [] n)