Haskell HXT用于提取值列表

时间:2010-10-09 18:17:48

标签: xml haskell hxt

我正在尝试用XPath和箭头同时通过HXT来解决问题,而我完全坚持如何思考这个问题。我有以下HTML:

<div>
<div class="c1">a</div> 
<div class="c2">b</div> 
<div class="c3">123</div> 
<div class="c4">234</div> 
</div>

我已经将其提取到HXT XmlTree中。我想做的是定义一个函数(我想?):

getValues :: [String] -> IOSArrow Xmltree [(String, String)]

如果用作getValues ["c1", "c2", "c3", "c4"],我会:

[("c1", "a"), ("c2", "b"), ("c3", "123"), ("c4", "234")]

请帮忙吗?

3 个答案:

答案 0 :(得分:2)

这是一种方法(我的类型更通用,我不使用XPath):

{-# LANGUAGE Arrows #-}
module Main where

import qualified Data.Map as M
import Text.XML.HXT.Arrow

classes :: (ArrowXml a) => a XmlTree (M.Map String String)
classes = listA (divs >>> divs >>> pairs) >>> arr M.fromList
  where
    divs = getChildren >>> hasName "div"
    pairs = proc div -> do
      cls <- getAttrValue "class" -< div
      val <- deep getText         -< div
      returnA -< (cls, val)

getValues :: (ArrowXml a) => [String] -> a XmlTree [(String, Maybe String)]
getValues cs = classes >>> arr (zip cs . lookupValues cs)
  where lookupValues cs m = map (flip M.lookup m) cs

main = do
  let xml = "<div><div class='c1'>a</div><div class='c2'>b</div>\
            \<div class='c3'>123</div><div class='c4'>234</div></div>"

  print =<< runX (readString [] xml >>> getValues ["c1", "c2", "c3", "c4"])

我可能会运行一个箭头来获取地图,然后进行查找,但这种方式也可以。


要回答关于listA的问题:divs >>> divs >>> pairs是一个类型为a XmlTree (String, String)的列表箭头 - 也就是说,它是一个非确定性计算,它采用XML树并返回字符串对。 / p>

arr M.fromList的类型为a [(String, String)] (M.Map String String)。这意味着我们不能仅仅使用divs >>> divs >>> pairs撰写它,因为类型不匹配。

listA解决了这个问题: divs >>> divs >>> pairs折叠为类型为a XmlTree [(String, String)]的确定版本,这正是我们所需要的。

答案 1 :(得分:0)

以下是使用HandsomeSoup

执行此操作的方法
-- For the join function.
import Data.String.Utils
import Text.HandsomeSoup
import Text.XML.HXT.Core

-- Of each element, get class attribute and text.
getItem = (this ! "class" &&& (this /> getText))  
getItems selectors = css (join "," selectors) >>> getItem

main = do
  let selectors = [".c1", ".c2", ".c3", ".c4"]
  items <- runX (readDocument [] "data.html" >>> getItems selectors)
  print items

data.html是HTML文件。

答案 2 :(得分:0)

即使距原始帖子已经10年了,这仍然是非常有用的建议。

对于在2020年仍受Haskell XML处理困扰的其他人,我可以确认第一个示例在以下系统上可以正常工作:

ghci --version Glorious Glasgow Haskell编译系统,版本8.8.4

Mac OS Catalina(10.15.7)

非常感谢您的帮助-这为我节省了很多时间。