Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 如何在HXT ;树?_Xml_Haskell_Hxt - Fatal编程技术网

Xml 如何在HXT ;树?

Xml 如何在HXT ;树?,xml,haskell,hxt,Xml,Haskell,Hxt,我有以下xml: <list> <recipient> <name></name> <lastname></lastname> <email></email> <phone></phone> <home></home> </recipient>

我有以下xml:

<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