Question

I am trying to extract tags from a xml file and write each one to a seperate file based on an attribute.

The extraction part isn't that hard:

*Main> ifs <- runX ( readDocument [withCurl [],withExpat yes] "file.xml" >>> getElement "TagName" >>> getAttrValue "Name" &&& this)
*Main> :t ifs
ifs :: [(String, XmlTree)]

I tried to map writeDocument over the second entries but had no sucess. I understand that i have to get it back into the IO Monad somehow ... but have no idea on how to achieve this.


for testing purposes i have extracted on of those XmlTrees from the result:

*Main> let x = (map snd ifs) !! 0
*Main> :t x
x :: XmlTree

I can run arrows on x like this:

*Main> runLA (getName) x
["TagName"]

But when i try to write it to a file i get error message indicating that i am not in the IO Monade (i think):

*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")'

Changing runLA to runIOSLA doesn't help:

*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

That's as far as i can get.

Update

As Travis Brown points out it is possible to do this in one arrow:

runX . applyA $ readDocument [withCurl [],withExpat yes] "file.xml" >>> getElement "Tag" >>> getAttrValue "DEF" &&& this >>> arr (\ (n,x) -> root [] [constA x] >>> writeDocument [] n)
Was it helpful?

Solution

Use root and constA to make an document root arrow out of your node:

runX (root [] [constA x] >>> writeDocument [] "test.xml")

This should work as expected.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top