Im writing a pickler for OpenTable xml files. It's the first time I use HXT, and I have some problems.
My first problem is that bindings is a list of multiple kinds of elements. How would I write the bindings pickler?
Im including the full source
Haskell data type:
module OpenTable
where
data OpenTable = OpenTable { meta :: Meta
, bindings :: [Binding]
} deriving (Read, Show)
data Meta = Meta { metaApiKeyURL :: Maybe String
, metaAuthor :: Maybe String
, metaDocumentationURL :: Maybe String
, metaDescription :: Maybe String
, metaSampleQuery :: Maybe String
} deriving (Read, Show)
data Binding = SelectBinding Select
| InsertBinding Insert
| UpdateBinding Update
| DeleteBinding Delete
deriving (Read, Show)
data Select = Select { selectItemPath :: Maybe String
, selectPollingFrequencySeconds :: Maybe Integer
, selectProduces :: Maybe String
, selectUrls :: [String]
, selectInputs :: [Input]
} deriving (Read, Show)
....
Parser:
module Main
where
import System.Environment
import Text.XML.HXT.Core
import OpenTable
main :: IO ()
main
= do
[file] <- getArgs
parseYQL file
return ()
instance XmlPickler OpenTable where
xpickle = xpOpenTable
xpOpenTable :: PU OpenTable
xpOpenTable
= xpElem "table" $
xpWrap ( uncurry OpenTable
, \ot -> (meta ot, bindings ot)) $
xpPair xpMeta xpBindings
instance XmlPickler Meta where
xpickle = xpMeta
xpMeta :: PU Meta
xpMeta
= xpElem "meta" $
xpWrap ( \ ((api, aut, doc, des, sam)) -> Meta api aut doc des sam
, \ m -> (metaApiKeyURL m, metaAuthor m, metaDocumentationURL m,
metaDescription m, metaSampleQuery m)) $
xp5Tuple
(xpOption $ xpElem "apiKeyUrl" xpText)
(xpOption $ xpElem "author" xpText)
(xpOption $ xpElem "documentationURL" xpText)
(xpOption $ xpElem "description" xpText)
(xpOption $ xpElem "sampleQuery" xpText)
xpBindings :: PU [Binding]
xpBindings = xpElem "bindings" $
xpList xpBinding
instance XmlPickler Binding where
xpickle = xpBinding
xpBinding :: PU Binding
xpBinding = undefined
parseYQL file
= runX ( xunpickleDocument xpOpenTable [] file
>>>
xpickleDocument xpOpenTable [] "dst.xml" )
OpenTable XML:
<?xml version="1.0" encoding="UTF-8"?>
<table xmlns="http://query.yahooapis.com/v1/schema/table.xsd">
<meta>
<sampleQuery>select * from {table} where q="this is a test" and target="de";</sampleQuery>
</meta>
<bindings>
<select itemPath="json" produces="JSON">
<urls>
<url>http://translate.google.com/translate_a/t?client=x&text={q}&sl={source}&tl={target}</url>
</urls>
<inputs>
<key id='q' type='xs:string' paramType='query' required="true" />
<key id='source' type='xs:string' paramType='path' default="auto" />
<key id='target' type='xs:string' paramType='path' required="true" />
</inputs>
</select>
</bindings>
</table>
HXT provides the
xpAlt :: (a -> Int) -> [PU a] -> PU afunction for sum data types. The first argument maps values of the sum typeatoInts which are then used as an index into the list ofPU as in the second argument, i.e. an appropriatePU awill be selected based on the theavalue passed to the function in the first argument.For your code, you might try something like: