我正在尝试生成具有混合内容节点(具有正文和子节点)的XML,如下所示:
<person>
some text
<hugo age="24">thingy</hugo>
</person>
我正在使用 xmlgen 库。
以下是我走了多远:
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
这无法编译,GHC 的错误消息对我来说是不可理解的(作为初学者):
$ 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")))'
我是否非常接近我需要的结果,或者我应该以不同的方式编写?
我尝试寻找 xmlgen 库的示例用法,但没有找到我的用例。任何帮助将不胜感激。
问题出在表达式中
(xtext "some text" :
(xelem "hugo" (xattr "age" "24" <#>
xtext "thingy")))
:
后面的部分(以 xelem "hugo"
开头)不是列表。调试此类问题的好方法是使用 ghci。这就是我最初所做的,ghci 很快将您引向正确的方向:
*Text.XML.Generator> :t xtext "some text" : xelem "hugo" (xattr "age" "24" <#> xtext "thingy")
<interactive>:1:21:
Couldn't match expected type `[Xml Elem]'
with actual type `Xml Elem'
In the return type of a call of `xelem'
In the second argument of `(:)', namely
`xelem "hugo" (xattr "age" "24" <#> xtext "thingy")'
In the expression:
xtext "some text"
: xelem "hugo" (xattr "age" "24" <#> xtext "thingy")
一个很好的问题是为什么GHC首先给出如此糟糕的错误消息。问题是xelem
的结果类型是重载的,实际上xelem
的类型是n -> MkElemRes n c
。您尝试在示例中使用的MkElemRes n c
的实例化确实是一种函数类型,因此示例的这一部分是正确的。但一般来说,MkElemRes n c
不需要是函数类型,这就是为什么 GHC 抱怨两个只期望一个参数(即类型 MkElemRes n c
的一个)的原因。
以下是原始问题的一种解决方案:
xelem "person" $
xelems [xtext "some text", xelem "hugo" (xattr "age" "24" <#> xtext "thingy")]
这是一个替代解决方案:
xelem "person" $ xtext "some text" <> xelem "hugo" (xattr "age" "24" <#> xtext "thingy")