2010-07-19 17 views
5

मैं एक आवेदन पर काम कर रहा हूँ, और मेरा काम सिर्फ आवेदन के लिए एक नमूना अजगर इंटरफेस विकसित करना है। आवेदन XML- आधारित दस्तावेज़ प्रदान कर सकते हैं, मैं HTTP GET प्रणाली द्वारा दस्तावेज़ प्राप्त कर सकते हैं, लेकिन समस्या यह XML- आधारित दस्तावेज़ कोई अंत तत्व नहीं होगा जिसका मतलब है कि अंतहीन है। मुझे पता है कि दस्तावेज़ SAX द्वारा संभाला जाना चाहिए, लेकिन अंतहीन समस्या से निपटने के लिए कैसे? कोई विचार, नमूना कोड?अजगर संभाल अंतहीन एक्सएमएल

+1

पायथन जनरेटर का पता लगाने के लिए एक अच्छा अवसर की तरह लगता है। –

उत्तर

2

दस्तावेज़ दस्तावेज़ में किसी तत्व के लिए एक बंद टैग हो जाता है कभी नहीं है, तो यह सही ढंग से नहीं बना है एक्सएमएल, किसी भी XML पार्सर के साथ कहर खेलने जा रहा है जो।

ऐसा कहा जाता है कि, पाइथन SAX2 एपीआई का उपयोग करना सबसे अच्छा तरीका प्रतीत होता है, लेकिन आपको यह निर्धारित करना होगा कि गुम क्लोज-टैग द्वारा इसे किस अपवाद को फेंक दिया जाएगा, इसे पकड़ें और इसे स्वयं संभालें।

जोड़ा गया

मान लें कि आप इस तरह एक XML दस्तावेज प्राप्त कर रहे हैं:

<? xml version="1.0" ?> 
<foo> 
    <bar>...</bar> 
    <bar>...</bar> 
    <bar>...</bar> 
    <bar>...</bar> 
    ... 

और आप एक बंद </foo> प्राप्त कभी नहीं। इस मामले में, एक SAX पार्सर कि bar तत्वों के लिए प्रतिक्रिया कर रहा है startElement(bar) और endElement(bar) के लिए घटनाओं की एक धारा जारी करेगा। संभवतः आप शुरुआत और अंत के बीच के सभी डेटा एकत्र करेंगे, और फिर अंत घटना को देखने के बाद इसे एक शॉट पर संसाधित करेंगे।

एक ही तरीका है इस लूप को रोकने के लिए बाहर क्रिया के माध्यम से होने जा रहा है: कार्रवाई करने के लिए पूर्व में परिभाषित bar तत्वों की संख्या, या पहले से समय की राशि है जो आप bar घटनाओं प्राप्त करने के लिए समर्पित करना चाहते हैं परिभाषित करते हैं। एसएक्स पार्सर को थ्रेड में चलाएं और फिर जब आप अपनी सीमा को दबाते हैं तो थ्रेड को मार दें। Sax-parser थ्रेड को समाप्त करने के लिए प्रतीक्षा करते समय आप अपनी मुख्य प्रक्रिया सोना चाहेंगे।

+0

मुझे अपवाद की उम्मीद नहीं होगी: बिंदु यह है कि एक्सएमएल स्ट्रीम में कोई ईओएफ नहीं है, इसलिए कोई त्रुटि स्थिति नहीं है। –

3

jabberpy में xmlstream मॉड्यूल (भी twisted से उपलब्ध है) पर एक नज़र डालें:

xmlstream.py एक्सएमएल धारा आधारित नेटवर्क प्रोटोकॉल को लागू करने के लिए सरल सुविधा प्रदान करता है। इसका उपयोग jabber.py के लिए आधार के रूप में किया जाता है।

xmlstream.py नेटवर्क कनेक्टिविटी और xml धारा के पार्स करने में सफल हुआ। जब एक पूरी 'प्रोटोकॉल तत्व' (xmlstreams जड़ का एक पूरा बच्चा जिसका अर्थ है) dipatch विधि एक 'नोड' इस संरचना का उदाहरण के साथ कहा जाता है पार्स किया गया है। नोड क्लास के लिए मामले में एक्सएमएल दस्तावेजों या 'प्रोटोकॉल तत्वों' में हेरफेर करने के लिए कक्षा की तरह एक बहुत ही सरल एक्सएमएल डोम है।

0

मुझे लगता है कि आपका एक्सएमएल मूल रूप से एक कंटेनर तत्व के तहत एकत्र किए गए समान XML तत्वों की एक सूची है।

<items> 
    <item> 
    <!-- content here --> 
    </item> 
    <item> 
    <!-- content here --> 
    </item> 
    <item> 
    <!-- content here --> 
    </item> 
</items> 

की तरह कुछ SAX जब अपने पार्सर हो जाता है और अंत घटना में, आप, पूरा आइटम पार्स ढेर को साफ करें और जो कुछ अन्य कोड पार्स आइटम से निपटने के लिए किया जाना चाहिए पर आइटम पारित कर सकते हैं।

def process(item) : 
    # App logic goes here 

class ItemsHandler(xml.sax.handler.ContentHandler) : 
    # Omitting __init__, startElement, and characters methods 
    # to store data on a stack during processing 

    def endElement(self, name) : 
    if name == "item" : 
     # create item from stored data on stack 
     parsed_item = self.parse_item_from_stack() 
     process(parsed_item) 

आवेदन तर्क काफी जटिल है, तो आप SAX एक अलग थ्रेड में पार्स करने डाल करने के लिए ताकि आप घटनाओं को नहीं करना चाहती हूँ।

0

यदि दस्तावेज़ अंतहीन है तो इसे पार्सर में खोलने से पहले मैन्युअल रूप से अंत टैग (मुख्य तत्व का) क्यों नहीं जोड़ना चाहिए? मुझे पायथन नहीं पता है लेकिन स्ट्रिंग के लिए </endtag> क्यों नहीं जोड़ें?

+0

बस: क्योंकि इस तरह के दस्तावेज़ का कोई अंत नहीं है। तो आप "" अंत में "जोड़ नहीं सकते"। – arilou

0

मैं पाइथन में तुरंत समाधान नहीं दे सकता, लेकिन आपको संकेत मिलेगा।

उस प्रकार का एक्सएमएल पार्सिंग StAX पार्सर्स द्वारा संभाला जाता है। यहां समस्या यह है कि एक एसएक्स-पार्सर घटनाओं को धक्का देता है, लेकिन घटनाओं को खींचने के लिए एसएक्सएक्स इंटरफेस को साबित करता है। एसएक्सएक्स मुख्य रूप से आंशिक एक्सएमएल पार्सिंग (एसओएपी संदेश से केवल शीर्षलेखों को पार्सिंग) के लिए उपयोग किया जाता है, और यह आपका मामला प्रतीत होता है।

मैंने पायथन मानक पुस्तकालय में एक स्टैक्स-जैसे पार्सर्स नहीं देखा है, लेकिन निश्चित रूप से एक होना चाहिए।

यूपीडी: एलएक्सएमएल (एक रैपर टीपी libxml2 के रूप में) similar functinality लगता है।

6

यह है कि मैं क्या एक अंतहीन एक्सएमएल धारा जो मैं किसी दूरस्थ कंप्यूटर से प्राप्त पार्स करने के लिए उपयोग करते हैं (मेरे मामले में मैं एक सॉकेट से कनेक्ट और socket.makefile 'आर' का उपयोग करें() फ़ाइल वस्तु बनाने के लिए)

है

19.12.2. IncrementalParser Objects

parser = xml.sax.make_parser(['xml.sax.IncrementalParser']) 
handler = FooHandler() 
parser.setContentHandler(handler) 

data = sockfile.readline() 
while (len(data) != 0): 
    parser.feed(data) 
    data = sockfilefile.readline() 
+1

वास्तव में ऐसा कोई प्रतीक नहीं है कि 'xml.sax.IncrementalParser' और' make_parser' 'मॉड्यूल की एक सूची की अपेक्षा करता है जिसमें' create_parser' फ़ंक्शन है। 'Xml.sax.xmlreader.IncrementalParser' है, लेकिन यह केवल एक इंटरफ़ेस होने के नाते 'फ़ीड' लागू नहीं करता है। सौभाग्य से डिफ़ॉल्ट पार्सर मॉड्यूल, 'xml.sax.expatreader', जो' make_parser' उपयोगकर्ता द्वारा प्रदत्त मॉड्यूल लोड करने में विफल होने के बाद लोड करने का प्रयास करता है, 'xml.sax.xmlreader लागू करता है। इन्टरमेंटल पार्सर'। इसलिए तर्क के बिना 'make_parse' को कॉल करना पर्याप्त है। – saaj

0

आप stdlib में xml.etree.ElementTree (या cElementTree गति के लिए) से iterparse फ़ंक्शन का उपयोग कर सकते हैं। (आप भी lxml इस्तेमाल कर सकते हैं)

चाल यहाँ वर्णित है: http://effbot.org/zone/element-iterparse.htm#incremental-parsing

उदाहरण बताता है कि आप वास्तव में क्या जरूरत है। यह अंतहीन फ़ाइलों के बारे में कुछ भी नहीं बताता है, लेकिन यह काम करेगा। (यह अभी भी जारी रहेगा)। सबसे महत्वपूर्ण बात: रूट तत्व को साफ़ करना न भूलें।

आसान और stdlib में उपलब्ध ;-)

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