haskell - 如何正确收集Hxt程序的命令行选项?

标签 haskell command-line xml-parsing hxt

我已经到达论文的第 3 部分。M. Ohlendorf 的 Haskell XML Toolbox 手册,其中包含处理 RDF 文档的示例

这是我编写的程序,

import Text.XML.HXT.Core
import System.Exit
import System.Environment
import Data.Maybe

main = do
  args       <- getArgs
  (al, src)  <- cmdLineOpts args
  [rc]       <- runX (processDocument al src)
  exitWith ( if rc >= c_err
             then ExitFailure (-1)
             else ExitSuccess
           )

cmdLineOpts :: [String] -> IO (Attributes, String)
cmdLineOpts []  = return ([("","")], "")
cmdLineOpts xss = return (zip [""] xss :: Attributes, last xss)

processDocument :: Attributes -> String -> IOSArrow b Int
processDocument al src =
    readDocument al src -- lecture du document en appliquant les attributes                                                                                            
    >>>
    removeAllWhiteSpace >>> propagateNamespaces
    >>>
    writeDocument al (fromMaybe "" (lookup a_output_file al))
    >>>
    getErrStatus

但我仍然遇到以下错误

hxtuto.hs:28:17:
    Couldn't match expected type `XIOSysState -> XIOSysState'
           against inferred type `(String, String)'
      Expected type: SysConfigList
      Inferred type: Attributes
    In the first argument of `readDocument', namely `al'
    In the first argument of `(>>>)', namely `readDocument al src'
Failed, modules loaded: none.

看来这是我的 cmdLineOpts 实现不太适合。

这里有什么问题吗?我该如何修复它?

感谢您的帮助!

最佳答案

由于 readDocument 和 writeDocument 的第一个参数都是 [SysConfig],因此您可能需要使用像 GetOpt 这样的包来处理从命令行读取文本并将其转换为所需对象的内务工作。我从论文第 50 页获取了“可用选项”列表,并使用当前对应的 SysConfig(来自 Text.XML.HXT.Arrow.XmlState.SystemConfig)创建了一个选项类型。除了针对当前特定应用程序定制的部分外,其余部分(例如 cmdLineOpts)直接取自 GetOpt 文档。

import System.Console.GetOpt
import System.Environment
import System.Exit 
import Text.XML.HXT.Core

data Options = Options {
    withvalidate :: SysConfig
  , withchecknamespaces :: SysConfig
  , withcanonicalize :: SysConfig
  , withremovews :: SysConfig
  , withtrace :: SysConfig
  , output_file :: String } 

defaultOptions = Options { withvalidate = (withValidate no)
                         , withchecknamespaces = (withCheckNamespaces no)
                         , withcanonicalize = (withCanonicalize no)
                         , withremovews = (withRemoveWS no)
                         , withtrace = (withTrace 0)
                         , output_file = "" } 

options :: [OptDescr (Options -> Options)]
options =
 [ Option ['V'] ["withValidate"] 
   (ReqArg (\v opts -> opts { withvalidate = withValidate (v == "yes") } ) "") 
   "perform DTD validation"
 , Option ['n'] ["withCheckNamespaces"] 
   (ReqArg (\n opts -> opts { withchecknamespaces = withCheckNamespaces (n == "yes") } ) "")
   "check namespaces"
 , Option ['c'] ["withCanonicalize"] 
   (ReqArg (\c opts -> opts { withcanonicalize = withCanonicalize (c == "yes") } ) "")
   "canonicalize document"
 , Option ['w'] ["withRemoveWS"] 
   (ReqArg (\w opts -> opts { withremovews = withRemoveWS (w == "yes") } ) "")
   "remove whitespace used for document indentation"
 , Option ['t'] ["withTrace"] 
   (ReqArg (\t opts -> opts { withtrace = withTrace (read t) } ) "")
   "set trace level" 
 , Option ['o'] ["outputFile"] 
   (ReqArg (\o opts -> opts { output_file = o } ) "") 
   "output file" ]

cmdLineOpts :: [String] -> IO (Options, [String])
cmdLineOpts argv =
    case getOpt Permute options argv of
      (o, n, []) -> return (foldl (flip id) defaultOptions o, n)
      (_, _, errs) -> ioError (userError (concat errs ++ usageInfo header options))
    where header = "Using: [OPTION ...]"

main :: IO ()
main = do (opts, (src:_)) <- cmdLineOpts =<< getArgs 
          [rc] <- runX $ processDocument opts src
          exitWith $ if rc >= c_err then ExitFailure (-1) else ExitSuccess

processDocument :: Options -> String -> IOSArrow b Int
processDocument (Options val ns can ws tr out) src =
    readDocument [val, ns, can, ws, tr] src >>> 
    removeAllWhiteSpace >>> propagateNamespaces >>>
    writeDocument [val, ns, can, ws, tr] out >>>
    getErrStatus

关于haskell - 如何正确收集Hxt程序的命令行选项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9719510/

相关文章:

android - XMLPullParser getName() 返回 null

java - 简单XML : element with elements list or text

inheritance - Aspectj项目在Eclipse中编译时不会在终端上编译

haskell - CPP : Macros in Haskell

debugging - 测试顶级函数内定义的内部函数并与之交互的最佳方法是什么?

python - 转换以前缀表示法给出的表达式,识别公共(public)子表达式和依赖项

javascript - 使用 node.js 的 Windows 命令行解释器

command-line - 暂停批处理文件一段时间

ios - 在 iOS swift 中解析 xml

haskell - 使用测试创建完整的 Haskell 堆栈