1

我正在尝试生成具有混合内容节点(具有正文和子节点)的 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 库的示例用法,但没有找到我的用例。任何帮助是极大的赞赏。

4

1 回答 1

1

问题在于表达式

(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有 type n -> MkElemRes n c。您尝试在示例中使用的实例化MkElemRes n c确实是一种函数类型,因此您示例的这一部分是正确的。但通常MkElemRes n c不需要是函数类型,这就是为什么 GHC 抱怨两个参数,它只需要一个(即 type 之一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")
于 2013-01-25T08:50:35.370 回答