2

我为 OpenTable xml 文件编写了一个pickler。这是我第一次使用HXT,我遇到了一些问题。

我的第一个问题是绑定是多种元素的列表。我将如何编写绑定pickler?

我包括完整的来源

Haskell 数据类型:

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)
....

解析器:

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" )

开放表 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&amp;text={q}&amp;sl={source}&amp;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>
4

1 回答 1

1

HXT 提供xpAlt :: (a -> Int) -> [PU a] -> PU a求和数据类型的功能。第一个参数将 sum 类型的值映射aInts,然后将其用作第二个参数中 s 列表的索引,即,将根据第一个参数中传递给函数的值选择PU a适当的值。PU aa

对于您的代码,您可以尝试以下操作:

xpBinding :: PU Binding
xpBinding = xpAlt tag ps
  where
    tag (SelectBinding s) = 0
    tag (InsertBinding i) = 1
    -- ...
    ps = [ xpSelectBinding
         , xpInsertBinding
         -- ...
         ]

xpSelectBinding :: PU Binding
xpSelectBinding = ...

xpInsertBinding :: PU Binding
xpInsertBinding = ...
于 2015-09-08T21:39:13.157 回答