我是Haskell的总新手,和我的第一个真正的问题 与Haskell我想解析一个巨大的带有HaXml SAX解析的XML文件。当你用Haskell(HaXml)进行SAX解析时,你如何保持“状态”?
我遇到的最大问题是如何找出包含任何特定“charData”SaxElement的 元素标记。如果我正在使用命令式语言编写 ,那么我只需要一个有状态的Array 对象,该对象在SAX事件发生时维护元素标记堆栈。当遇到“SAX.SaxElementOpen”为 时,I 会将元素名称推送到堆栈,并在遇到“SAX.SaxElementClose”时弹出一个。 然后,如果我得到了一个“SAX.SaxCharData”事件/元素,我只是看 堆栈的顶部,看看有什么标签它被装入英寸
现在,我试图解决在Haskell这个问题,我不知道 如何解决缺乏全局有状态变量的问题。我只有一个 模糊的概念Monads做什么,所以如果他们是解决方案,我可以使用 一个或两个。
这里是希望足够的代码来说明如何到目前为止,我已经得到了:
module Main where
import qualified Text.XML.HaXml.SAX as SAX
import Text.XML.HaXml
import Data.Maybe
import Text.XML.HaXml.Namespaces
main = let inputFilename = "/path/to/file.xml" in
do content <- readFile inputFilename
let (elements, error) = SAX.saxParse inputFilename content
mapM_ putStrLn (summarizeElements elements)
summarizeElements :: [SAX.SaxElement] -> [String]
summarizeElements elements = filter (\s -> length s > 0) $ map summarizeElement elements
summarizeElement :: SAX.SaxElement -> String
summarizeElement element = case element of
(SAX.SaxElementOpen name attrs) -> myProcessElem name attrs
(SAX.SaxCharData charData) -> myProcessCharData charData
(SAX.SaxElementTag name attrs) -> myProcessElem name attrs
_ -> ""
尝试一个状态monad。你可以通过在列表中存储一个状态来定义你自己的'push'和'pop'操作。 – fuz
我一直在看Monad国家,我不得不承认,在这一点上我感到非常困惑。 – dan