あるタイプの値コンストラクターを特定の属性の XML 属性値にシリアル化し、XML 属性値をそのタイプの値コンストラクターに逆シリアル化する xpickle を作成しようとしています。
次のデータがあります。
module Main where
import Text.XML.HXT.Core
newtype Things = Things [Thing]
data Thing = Thing (Maybe Property)
data Property = A | B
someThings :: Things
someThings = Things [ Thing (Just A)
, Thing Nothing
, Thing (Just B)
]
そして、これを次のようなものにシリアライズしたいと思います:
<things>
<thing property="a" />
<thing />
<thing property="b" />
</things>
これが私が取っているアプローチです:
instance XmlPickler Things where
xpickle = xpWrap ( \things -> Things things , \(Things things) -> things ) $
xpElem "things" $
xpThings
xpThings :: PU [Thing]
xpThings = xpList xpickle
instance XmlPickler Thing where
xpickle = xpElem "thing" $
xpWrap ( \p -> Thing p , \(Thing p) -> p ) $
xpProperty
xpProperty :: PU (Maybe Property)
xpProperty = xpOption $ xpAttr "property" xpPropertyValue
xpPropertyValue :: PU Property
xpPropertyValue = xpAlt tag ps
where
tag A = 1
tag B = 2
ps = [ xpTextAttr "a"
, xpTextAttr "b"
]
main :: IO ()
main = do
putStrLn $ showPickled [ withIndent yes ] someThings
return ()
ここでは、属性をxpProperty
作成または読み取り、値を計算するために使用します。値の値コンストラクターに応じて値を決定します。ここでの問題は、それが必要な場所で使用しようとしているということです。しかし、値の値コンストラクターに依存する値を生成する別の方法を見つけることはできません。@property
xpPropertyValue
xpPropertyValue
A
"a"
B
"b"
xpTextAttr
xpTextAttr
String -> PU String
PU Property
PU Property
Property