2010-10-09 15 views
5

Ich versuche meinen Weg durch HXT mit XPath und Pfeilen gleichzeitig zu finden und ich bin völlig fest daran, wie ich dieses Problem durchdenken kann. Ich habe die folgende HTML:Haskell HXT zum Extrahieren einer Werteliste

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

die ich in einem HXT XmlTree extrahiert habe. Was ich möchte, zu tun ist, eine Funktion zu definieren (glaube ich?):

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

deren Benutzung als getValues ["c1", "c2", "c3", "c4"], wird mich erhalten:

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

Hilfe bitte?

Antwort

2

Hier ist ein Ansatz (meine Typen sind etwas allgemeinere und ich bin mit XPath nicht):

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

ich wahrscheinlich einen Pfeil laufen würde die Karte zu bekommen und dann die Lookups tun, aber auf diese Weise funktioniert auch.


Ihre Frage zu listA zu beantworten: divs >>> divs >>> pairs ist eine Liste mit Pfeil Typ a XmlTree (String, String) -i.e., ist es eine nicht-deterministische Berechnung, die eine XML-Struktur nimmt und String-Paaren zurückgibt.

arr M.fromList hat Typ a [(String, String)] (M.Map String String). Das heißt, wir können es nicht einfach mit divs >>> divs >>> pairs zusammensetzen, da die Typen nicht zusammenpassen.

listA löst dieses Problem: es kollabiertdivs >>> divs >>> pairs in eine deterministische Version mit Typ a XmlTree [(String, String)], das ist genau das, was wir brauchen.

+0

Was macht listA? – Muchin

0

Hier ist ein Weg, es zu tun HandsomeSoup mit:

-- 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 ist die HTML-Datei.

Verwandte Themen