I am trying to generate XML with mixed content nodes (has both body text and children nodes), like the following:
<person>
some text
<hugo age="24">thingy</hugo>
</person>
I am using the xmlgen library.
Here's how far I got:
import Text.XML.Generator
import qualified Data.ByteString as B
makeElt = xelem "person" $
xelems $ (xtext "some text" :
(xelem "hugo" (xattr "age" "24" <#>
xtext "thingy")))
main = do
let elt = makeElt
B.putStr . xrender $ doc defaultDocInfo elt
This does not compile and GHC's error message is incomprehensible to me (as a beginner):
$ runhaskell test.hs
test.hs:6:24:
Couldn't match type `Elem' with `Xml Elem'
The function `xelem' is applied to two arguments,
but its type `[Char]
-> Text.XML.Generator.MkElemRes [Char] (Xml Attr, Xml Elem)'
has only one
In the second argument of `(:)', namely
`(xelem "hugo" (xattr "age" "24" <#> xtext "thingy"))'
In the second argument of `($)', namely
`(xtext "some text"
: (xelem "hugo" (xattr "age" "24" <#> xtext "thingy")))'
test.hs:6:24:
Couldn't match type `Xml' with `[]'
The function `xelem' is applied to two arguments,
but its type `[Char]
-> Text.XML.Generator.MkElemRes [Char] (Xml Attr, Xml Elem)'
has only one
In the second argument of `(:)', namely
`(xelem "hugo" (xattr "age" "24" <#> xtext "thingy"))'
In the second argument of `($)', namely
`(xtext "some text"
: (xelem "hugo" (xattr "age" "24" <#> xtext "thingy")))'
Am I quite close to the result that I need, or should I be writing this differently?
I tried looking for examples usage of the xmlgen library but didn't find my use-case. Any help is greatly appreciated.
The problem is in the expression
The part after the
:
(starting withxelem "hugo"
) is not a list. I good way to debug such type problems is using ghci. That's what I did in the first place, and the ghci quickly leads you in the right direction:A good question is why GHC give's such a bad error message in the first place. The problem is that the result type of
xelem
is overloaded, in factxelem
has typen -> MkElemRes n c
. The instantiation forMkElemRes n c
you are trying to use in your example is indeed a function type, so this part of your example is correct. But in generalMkElemRes n c
does not need to be a function type and that's why GHC complains about two arguments where it expects only one (namely one of typeMkElemRes n c
).Here are one solution to your original problem:
Here is an alternative solution: