Xml 如何在HXT ;树?
我有以下xml:Xml 如何在HXT ;树?,xml,haskell,hxt,Xml,Haskell,Hxt,我有以下xml: <list> <recipient> <name></name> <lastname></lastname> <email></email> <phone></phone> <home></home> </recipient>
<list>
<recipient>
<name></name>
<lastname></lastname>
<email></email>
<phone></phone>
<home></home>
</recipient>
<recipient>
</recipient>
</list>
我要做的是读取xml并获取收件人列表:[收件人]为此,我写了以下内容:
import Text.XML.HXT.Core
readMyXml :: FilePath -> IO [Recipient]
readMyXml path = do
-- lets read the doc
fe <- readFile path
let
-- parse it
doc = readString [withValidate no] fe
-- get all recipient nodes
reps <- getAllRep
-- the part I don't have
-- the only thing wrong in the following is the map function
-- I need an equivalent that runs on hxt trees
return $ map frmRep2Dat reps
-- ^
-- |
-- here
-- end of part I don't have
where
getAllRep = runX $ doc
>>> deep (hasName "list")
>>> multi (hasName "recipient")
frmRep2Dat branch = do
let
-- gets the recipient of a recipient node child
getV name = runX $
branch
>>> deep (hasName name)
>>> removeAllWhiteSpace
>>> deep getText
-- normaly there is no need to check because not maybe fields are
-- mandatory and should not be empty
getVal name = do
val <- getV name
case val of
[] -> ""
[""] -> ""
_ -> head val
-- some maybe wrapping
getMayVal name = do
val <- getV name
case val of
[] -> Nothing
[""] -> Nothing
_ -> Just (head val)
name <- getVal "name"
lastname <- getVal "lastname"
email <- getVal "email"
phone <- getMayVal "phone"
home <- getMayVal "home"
return $ Recipient name lastname email phone home
import Text.XML.HXT.Core
readMyXml::FilePath->IO[收件人]
readMyXml路径=do
--让我们读一下文件
fe>deep(hasName“列表”)
>>>多(hasName“收件人”)
frmRep2Dat分支=do
让
--获取收件人节点子节点的收件人
getV name=runX$
分支
>>>深(hasName name)
>>>删除空白
>>>深层格言
--正常情况下,不需要检查,因为可能没有字段
--必填项,不应为空
getVal name=do
瓦尔“
[""] -> ""
_->head val
--有些可能是包装
getMayVal name=do
什么都没有
[“”]->什么都没有
_->仅(头val)
name发现不需要遍历树。HXT已经做到了。
有一种从xml构建数据的方法比我写的那种简单。
我将整个readMyXml函数替换为:
readMyXml path = do
fi <- readFile path
let
doc = readString [withValidate no] fi
return =<< runX $ getRecipients doc
wrapStr a = if null a
then Nothing
else Just a
getD a = deep (hasName a)
>>> removeAllWhiteSpace
>>> deep getText
getMD a = getD a
>>^ wrapStr
getRecipients doc = doc
>>> deep (hasName "list")
>>> multi (hasName "recipient")
>>> proc y -> do
nime <- getD "name" -< y
lstn <- getD "lastname" -< y
mail <- getD "email" -< y
phon <- getMD "phone" -< y
homi <- getMD "home" -< y
returnA -< Recipient nime lstn mail phon homi
readMyXml路径=do
fi>removeAllWhiteSpace
>>>深层格言
getMD a=getD a
>>^包装机
getRecipients doc=doc
>>>深度(hasName“列表”)
>>>多(hasName“收件人”)
>>>程序y->do
经过思考,尼姆也许地图不是正确的等价物。在任何情况下,目标仍然是将树简化为收件人列表。任何函数(你也可以阅读箭头)都可以让我在树上进行迭代,并从迭代过程中构造一个列表。嗨,你能减少那里的代码量吗,我很乐意提供帮助,但我不会为一个10行的问题阅读50行左右的代码。同样,Haskell中的小顶级函数也可以,请不要把所有的东西都粉碎成一个,在那里
在某个时候,我有太多的小顶级函数。合并一些代码使我的代码更具可读性。我将尝试减少代码,但现在我找到了一个解决方案。谢谢
readMyXml path = do
fi <- readFile path
let
doc = readString [withValidate no] fi
return =<< runX $ getRecipients doc
wrapStr a = if null a
then Nothing
else Just a
getD a = deep (hasName a)
>>> removeAllWhiteSpace
>>> deep getText
getMD a = getD a
>>^ wrapStr
getRecipients doc = doc
>>> deep (hasName "list")
>>> multi (hasName "recipient")
>>> proc y -> do
nime <- getD "name" -< y
lstn <- getD "lastname" -< y
mail <- getD "email" -< y
phon <- getMD "phone" -< y
homi <- getMD "home" -< y
returnA -< Recipient nime lstn mail phon homi