我已经达到了论文的第3部分。 Haskell XML工具箱的食谱,以及M. Ohlendorf的处理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
的实现并不合适。
这是什么问题?我该如何解决?
感谢您的帮助!
答案 0 :(得分:1)
由于readDocument和writeDocument的第一个参数是[SysConfig],您可能希望使用像GetOpt这样的包来处理从命令行读取文本并将其转换为所需对象的内务处理。我从论文的第50页获取了“可用选项”列表,并使用当前的相应SysConfigs(来自Text.XML.HXT.Arrow.XmlState.SystemConfig)创建了一个Options类型。除了为特定应用程序定制的部件外,其余部分(例如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