2010-10-09 12 views
5

मैं एक ही समय में xPath और तीर के साथ HXT के माध्यम से अपने रास्ते लगाने की कोशिश कर रहा हूँ और मैं पूरी तरह से इस समस्या के माध्यम से सोचने के लिए पर अटक कर रहा हूँ की एक सूची निकालने के लिए। मुझे निम्नलिखित HTML मिल गया है:हास्केल HXT मूल्यों

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

मदद?

उत्तर

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) -i.e. एक सूची तीर है, यह एक गैर नियतात्मक गणना कि एक XML पेड़ लेता है और स्ट्रिंग जोड़े रिटर्न है।

arr M.fromList टाइप a [(String, String)] (M.Map String String) है। इसका मतलब यह है हम सिर्फ divs >>> divs >>> pairs साथ यह रचना नहीं कर सकते, क्योंकि प्रकार के मेल नहीं खाते।

listA इस समस्या का हल: यह गिरdivs >>> divs >>> pairs एक निश्चयात्मक संस्करण में प्रकार a XmlTree [(String, String)] साथ, जो कि हम वास्तव में क्या जरूरत है।

+0

लिस्टा क्या करता है? – Muchin

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 फ़ाइल है।