pulcher
pulcher

Reputation: 125

HXT: reuse "preparsed" data

I am trying to 'preparse' XML with HXT into [XmlTree] once and then reuse this data several times.

Below is my code:

{-# 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 )

If I parse beforehand:

λ: x <- runX parseRoot

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

How do I run something like this:

runX $ XYZ(x) >>> getWindow

or this:

runX $ XYZ(x) >>> getSomethingElse

Allowing me to reuse data in 'x'.

Upvotes: 1

Views: 72

Answers (2)

pulcher
pulcher

Reputation: 125

After reading more about arrows I found this:

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

Now using constA on an element of type XmlTree we get an arrow that we can reuse:

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

I have to use head x as x will be of type [XmlTree] but the second arrow expects XmlTree.

Upvotes: 1

Paul Johnson
Paul Johnson

Reputation: 17786

You need to do the same thing in parseDoc that you do in getWindow:

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

Upvotes: 1

Related Questions