Я никогда не задумывался над тем, как извлечь биты из документов XML, используя HaXML ; HXT удовлетворил все мои потребности.
{-# LANGUAGE Arrows #-}
import Data.Maybe
import Text.XML.HXT.Arrow
type Name = String
type Value = String
data LocalizedString = LS Name Value
getLocalizedStrings :: String -> Maybe [LocalizedString]
getLocalizedStrings = (.) listToMaybe . runLA $ xread >>> getRoot
atTag :: ArrowXml a => String -> a XmlTree XmlTree
atTag tag = deep $ isElem >>> hasName tag
getRoot :: ArrowXml a => a XmlTree [LocalizedString]
getRoot = atTag "root" >>> listA getElem
getElem :: ArrowXml a => a XmlTree LocalizedString
getElem = atTag "elem" >>> proc x -> do
name <- getAttrValue "name" -< x
value <- getChildren >>> getText -< x
returnA -< LS name value
Вы, вероятно, хотели бы немного больше проверять ошибки (т.е. не просто лениво использовать atTag
, как я; на самом деле убедитесь, что <root>
является root, <elem>
является прямым потомком и т. Д.), Но это работает просто отлично на вашем примере.
Теперь, если вам нужно введение в Arrow s, к сожалению, я не знаю ни одного хорошего. Я сам научился этому «брошен в океан, чтобы научиться плавать».
Следует помнить, что синтаксис proc
/ -<
является просто сахаром для базовых операций со стрелками (arr
, >>>
и т. Д.), Как и do
/ <-
- просто сахар для основных монадных операций (return
, >>=
и т. Д.). Следующее эквивалентно:
getAttrValue "name" &&& (getChildren >>> getText) >>^ uncurry LS
proc x -> do
name <- getAttrValue "name" -< x
value <- getChildren >>> getText -< x
returnA -< LS name value