I'm trying to figure out how to perform some XML transformations with HXT, but I can't figure out how to output an entire document to a string. While the documentation shows how to use readDocument
and writeDocument
, these run in IO
, and I'm trying to figure out how to do a pure transformation.
(Incidentally: why is so much of HXT defined as impure functions? One of the main advantages of Haskell is, in my opinion, that the compiler can guarantee the purity of functions. If I didn't care about that, I could have accomplished my XML goal already by writing my application in another language.)
I've figured out how to read an XML string with HXT:
Prelude Text.XML.HXT.Core> x = "<foo><bar>baz</bar></foo>"
Prelude Text.XML.HXT.Core> runLA xread x
[NTree (XTag "foo" []) [NTree (XTag "bar" []) [NTree (XText "baz") []]]]
That works, as one can see, as expected.
Next, I'd like to write the XmlTree
back to a String
:
Prelude Text.XML.HXT.Core> runLA (xread >>> writeDocumentToString []) x
["<bar>baz</bar>"]
This is the heart of my question: where's the foo
element?
Why doesn't that arrow round-trip? Why isn't the output "<foo><bar>baz</bar></foo>"
?
In order to trouble-shoot, I've tried to print the Haskell representation:
Prelude Text.XML.HXT.Core> runLA (xread >>> writeDocumentToString [withShowHaskell yes]) x
["NTree (XTag \"foo\" []) [NTree (XTag \"bar\" []) [NTree (XText \"baz\") []]]"]
In this representation, the outermost foo
element is still present.
One can also demonstrate this by printing the tree:
Prelude Text.XML.HXT.Core> putStrLn $ unlines $ runLA (xread >>> writeDocumentToString [withShowTree yes]) x
---XTag "foo"
|
+---XTag "bar"
|
+---XText "baz"
Again, it seems quite clear that the foo
element is still there.
How can I serialise an XmlTree
to a String
while preserving the entire document, including the root?