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にはタイプがであるということn -> MkElemRes n cです。例で使用しようとしているインスタンス化MkElemRes n cは確かに関数型であるため、例のこの部分は正しいです。ただし、一般MkElemRes n cに関数型である必要はありません。そのため、GHCは1つ(つまり1つの型)のみを期待する2つの引数について文句を言いMkElemRes n cます。

元の問題に対する1つの解決策は次のとおりです。

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 に答える