HXT:重复使用“预先准备”的数据

时间:2016-01-12 14:31:45

标签: xml haskell hxt

我试图用HXT将XML预先解析为[XmlTree]一次,然后多次重复使用这些数据。

以下是我的代码:

{-# LANGUAGE Arrows, NoMonomorphismRestriction #-}
import Text.XML.HXT.Core

parseXML = readDocument [ withValidate no
                        , withRemoveWS yes  -- throw away formating WS
                        ] 

atTag tag = deep (isElem >>> hasName tag)


data UiWindow = UiWindow {
    wndName :: String,
    wndNameLib :: String,
    wndChildren :: [UiWindow]
    } deriving (Show)

initUiWindow = UiWindow {
    wndName = "empty",
    wndNameLib = "",
    wndChildren = []
    }


parseDoc docName = runX $ parseXML fileName >>> getWindow
  where
    fileName = docName ++ ".xml"


getWindow = atTag "Window" >>> proc x -> do
    libraryItemName <- getAttrValue "libraryItemName" -< x
    name <- getAttrValue "name" -< x
    children <- arrIO parseDoc -< libraryItemName
    returnA -< initUiWindow { wndName = name, wndNameLib = libraryItemName, wndChildren = children}


documentName = "DOMDocument.xml"        

parseRoot = parseXML documentName

--runX (parseRoot >>> getWindow )

如果我事先解析:

λ: x <- runX parseRoot

λ: :t x
x :: [XmlTree]
λ: :t getWindow
getWindow :: IOSLA (XIOState ()) XmlTree UiWindow

我如何运行这样的东西:

runX $ XYZ(x) >>> getWindow

或者这个:

runX $ XYZ(x) >>> getSomethingElse

允许我重复使用'x'中的数据。

2 个答案:

答案 0 :(得分:1)

你需要在你在getWindow中执行的parseDoc中做同样的事情:

runX $ parseXML filename >>> proc myDoc -> do
    window <- getWindow -< myDoc
    something <- getSomethingElse -< myDoc

答案 1 :(得分:1)

在阅读了更多关于箭头的内容后,我发现了这一点:

λ: :t constA
constA :: ArrowList a => c -> a b c

现在在constA类型的元素上使用XmlTree,我们会得到一个可以重复使用的箭头:

main = do
  x <- runX parseRoot
  windows <- runX $ constA (head x) >>> getWindow
  doors <- runX $ constA (head x) >>> getDoor

我必须使用head x,因为x类型为[XmlTree],但第二个箭头需要XmlTree