2010-10-10 11 views
27

पास्कर निष्पादित करने के लिए मैंने अभी तक सभी उदाहरणों को हास्केल एक्सएमएल टूलकिट, एचएफटी का उपयोग करके देखा है, runX का उपयोग करता है। आईओ मोनैड के अंदर runX रन। आईओ के बाहर इस एक्सएमएल पार्सर का उपयोग करने का कोई तरीका है? मुझे एक शुद्ध ऑपरेशन माना जाता है, समझ में नहीं आता कि मुझे आईओ के अंदर क्यों मजबूर होना पड़ा।आईओ के बाहर हास्केल एचएफटी चल रहा है?

+1

एक त्वरित नज़र यह मुझे देखता है जैसे 'runX' एक्सएमएल फ़ाइल पढ़ता है और इस प्रकार आईओ को अशुद्ध करता है। – alternative

+1

मुझे लगता है कि एचएफटी का पार्सर एक 'ऑनलाइन' पार्सर है यानी आउटपुट उत्पादन शुरू करने के लिए पूरे इनपुट को पढ़ने की आवश्यकता नहीं है। इसका उछाल यह है कि (कम से कम सिद्धांत में) यह निरंतर स्मृति पदचिह्न के साथ चला सकता है, नकारात्मकता यह है कि इसे मांग पर इनपुट के "भाग" को पढ़ना है, इसलिए आईओ में होना चाहिए। –

+2

लेकिन आलसी आईओ का उपयोग करके इसे आसानी से हल नहीं किया जा सका? उदाहरण के लिए, उच्च-प्रदर्शन एक्सएमएल-पार्सिंग प्राप्त करने के लिए, अभी मैं हेक्सपेट (बाइटस्ट्रिंग्स, और आलसी सैक्स-पार्सिंग के लिए) का उपयोग करता हूं और पॉलीपरसे (पॉली.लाज़ी।) मुझे लगातार मेमोरी पैरों के निशान, तेज प्रसंस्करण, और * सभी * पार्सिंग शुद्ध कार्यों में किया जाता है! –

उत्तर

28

IO के बाहर एक XML स्ट्रिंग को पार्स करने के लिए आप के साथ HXT के xread का उपयोग कर सकते हैं।

xread :: ArrowXml a => a String XmlTree 

इसका मतलब है आप प्रकार (ArrowXml a) => a XmlTree Whatever के किसी भी तीर एक a String Whatever पाने के लिए के साथ यह रचना कर सकते हैं:

xread निम्न प्रकार है।

runLArunX तरह है, लेकिन प्रकार LA की बातों के लिए:

runLA :: LA a b -> a -> [b] 

LAArrowXml का एक उदाहरण है।

{-# 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 >>> 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) >>> unlistA 
    where lookupValues cs m = map (flip M.lookup m) cs 

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

values :: [(String, Maybe String)] 
values = runLA (xread >>> getValues ["c1", "c2", "c3", "c4"]) xml 

main = print values 

classes और getValues पिछले के समान हैं:

यह सब एक साथ my answer के निम्न संस्करण अपने पिछले प्रश्न के HXT एक स्ट्रिंग अच्छी तरह से गठित XML युक्त पार्स करने के लिए उपयोग करता है किसी भी IO शामिल बिना कहें, अपेक्षित इनपुट और आउटपुट के अनुरूप कुछ मामूली परिवर्तनों के साथ संस्करण। मुख्य अंतर यह है कि हम और runX के बजाय xread और runLA का उपयोग करते हैं।

एक आलसी ByteString जैसा कुछ भी पढ़ने में सक्षम होना अच्छा होगा, लेकिन जहां तक ​​मुझे पता है कि यह वर्तमान में एचएफटी के साथ संभव नहीं है।


अन्य चीजों के एक जोड़े: आप कर सकते हैं IO बिना इस तरह से पार्स तार, लेकिन यह शायद जब भी आप कर सकते हैं runX उपयोग करना बेहतर है: यह आप पार्सर, त्रुटि संदेशों में से विन्यास पर अधिक नियंत्रण देता , आदि

इसके अलावा: मैं उदाहरण में कोड सरल और आसान विस्तार करने के लिए करने की कोशिश की, लेकिन Control.Arrow और Control.Arrow.ArrowList में combinators यह संभव तीर के साथ और अधिक संक्षेप में यदि आप चाहें तो काम करने के लिए बनाते हैं। निम्नलिखित उदाहरण के लिए, classes के किसी समान परिभाषा है:

classes = (getChildren >>> hasName "div" >>> pairs) >. M.fromList 
    where pairs = getAttrValue "class" &&& deep getText 
+0

हाय ट्रैविस। एक दम बढ़िया। एचएफटी के साथ पकड़ने के मेरे प्रयास में आपकी मदद बहुत उपयोगी है। – Muchin

1

ट्रैविस ब्राउन के जवाब काफी मददगार था। मैं बस अपना खुद का समाधान जोड़ना चाहता हूं, जो मुझे लगता है कि थोड़ा और सामान्य है (एक ही कार्य का उपयोग करके, समस्या-विशिष्ट मुद्दों को अनदेखा कर रहा है)।

मैं पहले से unpickling गया था:

upIO  :: XmlPickler a => String -> IO [a] 
upIO str = runX $ readString [] str >>> arrL (maybeToList . unpickleDoc xpickle) 

जो मैं यह करने के लिए बदलने के लिए कर रहा था:

upPure :: XmlPickler a => String -> [a] 
upPure str = runLA (xreadDoc >>> arrL (maybeToList . unpickleDoc xpickle)) str 

मैं पूरी तरह से उसके साथ सहमत हैं कि यह कर आप के विन्यास पर कम नियंत्रण देता है पार्सर इत्यादि, जो दुर्भाग्यपूर्ण है।

संबंधित मुद्दे